├── .appcast.xml ├── .bundle └── config ├── .gitignore ├── .ruby-version ├── .xcode-version ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Scripts ├── Build-Phases │ ├── copy_framework.sh │ └── install_using_xcode.sh └── notarize-plugin.sh ├── SymbolNameAutocomplete.xcodeproj └── project.pbxproj ├── SymbolNameAutocomplete ├── AnalyticsTrackingID.h ├── CSNSuggestionController.h ├── CSNSuggestionController.m ├── CSNSuggestionsWindowController.h ├── CSNSuggestionsWindowController.m ├── Categories │ ├── NSColor+Additions.h │ └── NSColor+Additions.m ├── Headers │ ├── CHSheetController.h │ ├── CHWindowController.h │ ├── MSCreateSymbolNamingSheet.h │ ├── MSDocumentData.h │ └── MSSymbolMaster.h ├── Info.plist ├── Models │ ├── CSNFetchResult.h │ ├── CSNFetchResult.m │ ├── CSNNameTokenizer.h │ ├── CSNNameTokenizer.m │ ├── CSNSymbolMasterItem.h │ ├── CSNSymbolMasterItem.m │ ├── CSNSymbolRepository.h │ └── CSNSymbolRepository.m ├── SymbolNameAutocomplete.h ├── SymbolNameAutocompletePluginController.h ├── SymbolNameAutocompletePluginController.m ├── Views │ ├── CSNRowView.h │ ├── CSNRowView.m │ ├── CSNSuggestionCell.h │ ├── CSNSuggestionCell.m │ ├── CSNSuggestionsTableView.h │ └── CSNSuggestionsTableView.m └── _Headers │ ├── CHSheetController.h │ ├── CHWindowController.h │ ├── MSCreateSymbolNamingSheet.h │ ├── MSDocumentData.h │ └── NSToolbarDelegate-Protocol.h ├── SymbolNameAutocompleteTests ├── CSNNameTokenizerTests.m ├── CSNSymbolRepositoryTests.m └── Info.plist ├── docs └── assets │ └── symbol_name_autocomplete.gif ├── fastlane ├── Fastfile └── README.md ├── package-lock.json ├── package.json ├── plugin ├── img │ └── icon.png ├── manifest.json └── src │ └── index.js └── vendor └── cache ├── CFPropertyList-3.0.3.gem ├── addressable-2.8.0.gem ├── artifactory-3.0.15.gem ├── atomos-0.1.3.gem ├── aws-eventstream-1.1.1.gem ├── aws-partitions-1.473.0.gem ├── aws-sdk-core-3.115.0.gem ├── aws-sdk-kms-1.44.0.gem ├── aws-sdk-s3-1.96.1.gem ├── aws-sigv4-1.2.3.gem ├── babosa-1.0.4.gem ├── claide-1.0.3.gem ├── colored-1.2.gem ├── colored2-3.1.2.gem ├── commander-4.6.0.gem ├── declarative-0.0.20.gem ├── digest-crc-0.6.3.gem ├── domain_name-0.5.20190701.gem ├── dotenv-2.7.6.gem ├── emoji_regex-3.2.2.gem ├── excon-0.83.0.gem ├── faraday-1.5.0.gem ├── faraday-cookie_jar-0.0.7.gem ├── faraday-em_http-1.0.0.gem ├── faraday-em_synchrony-1.0.0.gem ├── faraday-excon-1.1.0.gem ├── faraday-httpclient-1.0.1.gem ├── faraday-net_http-1.0.1.gem ├── faraday-net_http_persistent-1.1.0.gem ├── faraday-patron-1.0.0.gem ├── faraday_middleware-1.0.0.gem ├── fastimage-2.2.4.gem ├── fastlane-2.187.0.gem ├── gh_inspector-1.1.3.gem ├── google-apis-androidpublisher_v3-0.8.0.gem ├── google-apis-core-0.4.0.gem ├── google-apis-iamcredentials_v1-0.6.0.gem ├── google-apis-playcustomapp_v1-0.5.0.gem ├── google-apis-storage_v1-0.6.0.gem ├── google-cloud-core-1.6.0.gem ├── google-cloud-env-1.5.0.gem ├── google-cloud-errors-1.1.0.gem ├── google-cloud-storage-1.34.0.gem ├── googleauth-0.16.2.gem ├── highline-2.0.3.gem ├── http-cookie-1.0.4.gem ├── httpclient-2.8.3.gem ├── jmespath-1.4.0.gem ├── json-2.5.1.gem ├── jwt-2.2.3.gem ├── memoist-0.16.2.gem ├── mini_magick-4.11.0.gem ├── mini_mime-1.1.0.gem ├── multi_json-1.15.0.gem ├── multipart-post-2.0.0.gem ├── nanaimo-0.3.0.gem ├── naturally-2.2.1.gem ├── os-1.1.1.gem ├── plist-3.6.0.gem ├── public_suffix-4.0.6.gem ├── rake-13.0.4.gem ├── representable-3.1.1.gem ├── retriable-3.1.2.gem ├── rexml-3.2.5.gem ├── rouge-2.0.7.gem ├── ruby2_keywords-0.0.4.gem ├── rubyzip-2.3.2.gem ├── security-0.1.3.gem ├── signet-0.15.0.gem ├── simctl-1.6.8.gem ├── terminal-notifier-2.0.0.gem ├── terminal-table-1.8.0.gem ├── trailblazer-option-0.1.1.gem ├── tty-cursor-0.7.1.gem ├── tty-screen-0.8.1.gem ├── tty-spinner-0.9.3.gem ├── uber-0.1.0.gem ├── unf-0.1.4.gem ├── unf_ext-0.0.7.7.gem ├── unicode-display_width-1.7.0.gem ├── webrick-1.7.0.gem ├── word_wrap-1.0.0.gem ├── xcodeproj-1.20.0.gem ├── xcpretty-0.3.0.gem └── xcpretty-travis-formatter-1.0.1.gem /.appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SymbolNameAutocomplete 5 | Autocomplete symbol name when create it. 6 | en 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Version 0.5.2 30 | 31 | 32 | <ul> 33 | <li>Fix appcast URL on manifest.json</li> 34 | </ul> 35 | 36 | 37 | 38 | 39 | 40 | Version 0.5.1 41 | 42 | 43 | <ul> 44 | <li>Fix insertion behavior</li> 45 | </ul> 46 | 47 | 48 | 49 | 50 | 51 | Version 0.5.0 52 | 53 | 54 | <ul> 55 | <li>First release!</li> 56 | </ul> 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_PATH: "vendor/bundle" 3 | BUNDLE_BIN: "vendor/bin" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /fastlane/report.xml 2 | vendor/bundle 3 | vendor/bin 4 | /.skpmrc 5 | SymbolNameAutocomplete.sketchplugin 6 | /node_modules 7 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.0.0 2 | -------------------------------------------------------------------------------- /.xcode-version: -------------------------------------------------------------------------------- 1 | 12.5 -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } 6 | 7 | gem "fastlane", "2.187.0" -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.3) 5 | addressable (2.8.0) 6 | public_suffix (>= 2.0.2, < 5.0) 7 | artifactory (3.0.15) 8 | atomos (0.1.3) 9 | aws-eventstream (1.1.1) 10 | aws-partitions (1.473.0) 11 | aws-sdk-core (3.115.0) 12 | aws-eventstream (~> 1, >= 1.0.2) 13 | aws-partitions (~> 1, >= 1.239.0) 14 | aws-sigv4 (~> 1.1) 15 | jmespath (~> 1.0) 16 | aws-sdk-kms (1.44.0) 17 | aws-sdk-core (~> 3, >= 3.112.0) 18 | aws-sigv4 (~> 1.1) 19 | aws-sdk-s3 (1.96.1) 20 | aws-sdk-core (~> 3, >= 3.112.0) 21 | aws-sdk-kms (~> 1) 22 | aws-sigv4 (~> 1.1) 23 | aws-sigv4 (1.2.3) 24 | aws-eventstream (~> 1, >= 1.0.2) 25 | babosa (1.0.4) 26 | claide (1.0.3) 27 | colored (1.2) 28 | colored2 (3.1.2) 29 | commander (4.6.0) 30 | highline (~> 2.0.0) 31 | declarative (0.0.20) 32 | digest-crc (0.6.3) 33 | rake (>= 12.0.0, < 14.0.0) 34 | domain_name (0.5.20190701) 35 | unf (>= 0.0.5, < 1.0.0) 36 | dotenv (2.7.6) 37 | emoji_regex (3.2.2) 38 | excon (0.83.0) 39 | faraday (1.5.0) 40 | faraday-em_http (~> 1.0) 41 | faraday-em_synchrony (~> 1.0) 42 | faraday-excon (~> 1.1) 43 | faraday-httpclient (~> 1.0.1) 44 | faraday-net_http (~> 1.0) 45 | faraday-net_http_persistent (~> 1.1) 46 | faraday-patron (~> 1.0) 47 | multipart-post (>= 1.2, < 3) 48 | ruby2_keywords (>= 0.0.4) 49 | faraday-cookie_jar (0.0.7) 50 | faraday (>= 0.8.0) 51 | http-cookie (~> 1.0.0) 52 | faraday-em_http (1.0.0) 53 | faraday-em_synchrony (1.0.0) 54 | faraday-excon (1.1.0) 55 | faraday-httpclient (1.0.1) 56 | faraday-net_http (1.0.1) 57 | faraday-net_http_persistent (1.1.0) 58 | faraday-patron (1.0.0) 59 | faraday_middleware (1.0.0) 60 | faraday (~> 1.0) 61 | fastimage (2.2.4) 62 | fastlane (2.187.0) 63 | CFPropertyList (>= 2.3, < 4.0.0) 64 | addressable (>= 2.3, < 3.0.0) 65 | artifactory (~> 3.0) 66 | aws-sdk-s3 (~> 1.0) 67 | babosa (>= 1.0.3, < 2.0.0) 68 | bundler (>= 1.12.0, < 3.0.0) 69 | colored 70 | commander (~> 4.6) 71 | dotenv (>= 2.1.1, < 3.0.0) 72 | emoji_regex (>= 0.1, < 4.0) 73 | excon (>= 0.71.0, < 1.0.0) 74 | faraday (~> 1.0) 75 | faraday-cookie_jar (~> 0.0.6) 76 | faraday_middleware (~> 1.0) 77 | fastimage (>= 2.1.0, < 3.0.0) 78 | gh_inspector (>= 1.1.2, < 2.0.0) 79 | google-apis-androidpublisher_v3 (~> 0.1) 80 | google-apis-playcustomapp_v1 (~> 0.1) 81 | google-cloud-storage (~> 1.31) 82 | highline (~> 2.0) 83 | json (< 3.0.0) 84 | jwt (>= 2.1.0, < 3) 85 | mini_magick (>= 4.9.4, < 5.0.0) 86 | multipart-post (~> 2.0.0) 87 | naturally (~> 2.2) 88 | plist (>= 3.1.0, < 4.0.0) 89 | rubyzip (>= 2.0.0, < 3.0.0) 90 | security (= 0.1.3) 91 | simctl (~> 1.6.3) 92 | terminal-notifier (>= 2.0.0, < 3.0.0) 93 | terminal-table (>= 1.4.5, < 2.0.0) 94 | tty-screen (>= 0.6.3, < 1.0.0) 95 | tty-spinner (>= 0.8.0, < 1.0.0) 96 | word_wrap (~> 1.0.0) 97 | xcodeproj (>= 1.13.0, < 2.0.0) 98 | xcpretty (~> 0.3.0) 99 | xcpretty-travis-formatter (>= 0.0.3) 100 | gh_inspector (1.1.3) 101 | google-apis-androidpublisher_v3 (0.8.0) 102 | google-apis-core (>= 0.4, < 2.a) 103 | google-apis-core (0.4.0) 104 | addressable (~> 2.5, >= 2.5.1) 105 | googleauth (>= 0.16.2, < 2.a) 106 | httpclient (>= 2.8.1, < 3.a) 107 | mini_mime (~> 1.0) 108 | representable (~> 3.0) 109 | retriable (>= 2.0, < 4.a) 110 | rexml 111 | webrick 112 | google-apis-iamcredentials_v1 (0.6.0) 113 | google-apis-core (>= 0.4, < 2.a) 114 | google-apis-playcustomapp_v1 (0.5.0) 115 | google-apis-core (>= 0.4, < 2.a) 116 | google-apis-storage_v1 (0.6.0) 117 | google-apis-core (>= 0.4, < 2.a) 118 | google-cloud-core (1.6.0) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-errors (~> 1.0) 121 | google-cloud-env (1.5.0) 122 | faraday (>= 0.17.3, < 2.0) 123 | google-cloud-errors (1.1.0) 124 | google-cloud-storage (1.34.0) 125 | addressable (~> 2.5) 126 | digest-crc (~> 0.4) 127 | google-apis-iamcredentials_v1 (~> 0.1) 128 | google-apis-storage_v1 (~> 0.1) 129 | google-cloud-core (~> 1.6) 130 | googleauth (>= 0.16.2, < 2.a) 131 | mini_mime (~> 1.0) 132 | googleauth (0.16.2) 133 | faraday (>= 0.17.3, < 2.0) 134 | jwt (>= 1.4, < 3.0) 135 | memoist (~> 0.16) 136 | multi_json (~> 1.11) 137 | os (>= 0.9, < 2.0) 138 | signet (~> 0.14) 139 | highline (2.0.3) 140 | http-cookie (1.0.4) 141 | domain_name (~> 0.5) 142 | httpclient (2.8.3) 143 | jmespath (1.4.0) 144 | json (2.5.1) 145 | jwt (2.2.3) 146 | memoist (0.16.2) 147 | mini_magick (4.11.0) 148 | mini_mime (1.1.0) 149 | multi_json (1.15.0) 150 | multipart-post (2.0.0) 151 | nanaimo (0.3.0) 152 | naturally (2.2.1) 153 | os (1.1.1) 154 | plist (3.6.0) 155 | public_suffix (4.0.6) 156 | rake (13.0.4) 157 | representable (3.1.1) 158 | declarative (< 0.1.0) 159 | trailblazer-option (>= 0.1.1, < 0.2.0) 160 | uber (< 0.2.0) 161 | retriable (3.1.2) 162 | rexml (3.2.5) 163 | rouge (2.0.7) 164 | ruby2_keywords (0.0.4) 165 | rubyzip (2.3.2) 166 | security (0.1.3) 167 | signet (0.15.0) 168 | addressable (~> 2.3) 169 | faraday (>= 0.17.3, < 2.0) 170 | jwt (>= 1.5, < 3.0) 171 | multi_json (~> 1.10) 172 | simctl (1.6.8) 173 | CFPropertyList 174 | naturally 175 | terminal-notifier (2.0.0) 176 | terminal-table (1.8.0) 177 | unicode-display_width (~> 1.1, >= 1.1.1) 178 | trailblazer-option (0.1.1) 179 | tty-cursor (0.7.1) 180 | tty-screen (0.8.1) 181 | tty-spinner (0.9.3) 182 | tty-cursor (~> 0.7) 183 | uber (0.1.0) 184 | unf (0.1.4) 185 | unf_ext 186 | unf_ext (0.0.7.7) 187 | unicode-display_width (1.7.0) 188 | webrick (1.7.0) 189 | word_wrap (1.0.0) 190 | xcodeproj (1.20.0) 191 | CFPropertyList (>= 2.3.3, < 4.0) 192 | atomos (~> 0.1.3) 193 | claide (>= 1.0.2, < 2.0) 194 | colored2 (~> 3.1) 195 | nanaimo (~> 0.3.0) 196 | rexml (~> 3.2.4) 197 | xcpretty (0.3.0) 198 | rouge (~> 2.0.7) 199 | xcpretty-travis-formatter (1.0.1) 200 | xcpretty (~> 0.2, >= 0.0.7) 201 | 202 | PLATFORMS 203 | ruby 204 | 205 | DEPENDENCIES 206 | fastlane (= 2.187.0) 207 | 208 | BUNDLED WITH 209 | 2.2.3 210 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 griffin-stewie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SymbolNameAutocomplete 2 | 3 | This [Sketch](https://www.sketchapp.com/) plugin gives you autocompletion of symbol names when creating a symbol. 4 | 5 | ![gif](docs/assets/symbol_name_autocomplete.gif) 6 | 7 | ## Install 8 | 9 | - Downloads latest plugin from [here](https://github.com/griffin-stewie/SymbolNameAutocomplete/releases/latest). 10 | - Unzip it, and doble click `SymbolNameAutocomplete.sketchplugin` 11 | 12 | ## How it works 13 | 14 | 1. [Create a new symbol](https://www.sketchapp.com/docs/symbols/creating-symbols/). 15 | 2. Type symbol name, this plugin shows symbol name in a list if you already have existing symbols which matching name. 16 | 17 | This plugin treats group of names. 18 | 19 | You can hit `↓`, then this plugin shows all available names of symbol. 20 | 21 | ## Credits 22 | 23 | - [griffin-stewie](https://griffin-stewie.github.io/): Developer 24 | - [Poem](https://dribbble.com/poem_f): Icon Designer 25 | - Special thanks to [zeplin/emoji\-autocomplete\-sketch\-plugin](https://github.com/zeplin/emoji-autocomplete-sketch-plugin) -------------------------------------------------------------------------------- /Scripts/Build-Phases/copy_framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$BUILD_FROM_FASTLANE" ]; then 4 | echo "Build from fastlane. skip execute Install plugin phase." 5 | exit 0 6 | fi 7 | 8 | if [ ! -e "$SRCROOT/SymbolNameAutocomplete.sketchplugin" ]; then 9 | echo "Run 'npm run postinstall' or 'npm run build' first." 10 | exit 1 11 | fi 12 | 13 | ## This script is for using inside Xcode's Run Script Phase to package framework as .sketchplugin and putitng it as symbolic link. 14 | ## It means that all you have to do to debug using Xcode is just "Run" then automatilcally install my sketchplugin. 15 | 16 | echo "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME" 17 | echo "$SRCROOT/SymbolNameAutocomplete.sketchplugin/Resources/$FULL_PRODUCT_NAME" 18 | 19 | cp -rf "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME" "$SRCROOT/SymbolNameAutocomplete.sketchplugin/Contents/Resources/$FULL_PRODUCT_NAME" 20 | -------------------------------------------------------------------------------- /Scripts/Build-Phases/install_using_xcode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$BUILD_FROM_FASTLANE" ]; then 4 | echo "Build from fastlane. skip execute Install plugin phase." 5 | exit 0 6 | fi 7 | 8 | ## This script is for using inside Xcode's Run Script Phase to package framework as .sketchplugin and putitng it as symbolic link. 9 | ## It means that all you have to do to debug using Xcode is just "Run" then automatilcally install my sketchplugin. 10 | 11 | export LC_ALL=en_US.UTF-8 12 | export LANG=en_US.UTF-8 13 | 14 | ## set a path for `bundler` if you have it on different path. 15 | BUNDLER_PATH=~/.rbenv/shims/bundler 16 | 17 | ## run fastlane "install" lane 18 | echo "あああ" 19 | echo $CONFIGURATION_BUILD_DIR 20 | 21 | $BUNDLER_PATH exec fastlane mac install build_dir:$CONFIGURATION_BUILD_DIR -------------------------------------------------------------------------------- /Scripts/notarize-plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | bundle exec fastlane mac notarize_plugin zip:$1 -------------------------------------------------------------------------------- /SymbolNameAutocomplete.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D0FF4A9A21A69229000FA0DC /* SymbolNameAutocomplete.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0FF4A9021A69229000FA0DC /* SymbolNameAutocomplete.framework */; }; 11 | D0FF4AA121A69229000FA0DC /* SymbolNameAutocomplete.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FF4A9321A69229000FA0DC /* SymbolNameAutocomplete.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | D0FF4AAC21A692F3000FA0DC /* SymbolNameAutocompletePluginController.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FF4AAA21A692F3000FA0DC /* SymbolNameAutocompletePluginController.h */; }; 13 | D0FF4AAD21A692F3000FA0DC /* SymbolNameAutocompletePluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = D0FF4AAB21A692F3000FA0DC /* SymbolNameAutocompletePluginController.m */; }; 14 | D0FF4AB821A69952000FA0DC /* CSNSuggestionController.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FF4AB621A69952000FA0DC /* CSNSuggestionController.h */; }; 15 | D0FF4AB921A69952000FA0DC /* CSNSuggestionController.m in Sources */ = {isa = PBXBuildFile; fileRef = D0FF4AB721A69952000FA0DC /* CSNSuggestionController.m */; }; 16 | D0FF4ABC21A6998B000FA0DC /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0FF4ABB21A6998B000FA0DC /* AppKit.framework */; }; 17 | E3A78DDF21AD8A94007228F8 /* CHSheetController.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A78DDB21AD8A94007228F8 /* CHSheetController.h */; }; 18 | E3A78DE021AD8A94007228F8 /* MSSymbolMaster.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A78DDC21AD8A94007228F8 /* MSSymbolMaster.h */; }; 19 | E3A78DE121AD8A94007228F8 /* MSCreateSymbolNamingSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A78DDD21AD8A94007228F8 /* MSCreateSymbolNamingSheet.h */; }; 20 | E3A78DE221AD8A94007228F8 /* MSDocumentData.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A78DDE21AD8A94007228F8 /* MSDocumentData.h */; }; 21 | E3A78DE421AD8AF8007228F8 /* CHWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A78DE321AD8AF8007228F8 /* CHWindowController.h */; }; 22 | E3A96E6B21A7980500CC6B73 /* CSNSymbolRepositoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E3A96E6A21A7980500CC6B73 /* CSNSymbolRepositoryTests.m */; }; 23 | E3A96E6C21A7981800CC6B73 /* CSNSymbolRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = E3E49E5121A6D778001BBB19 /* CSNSymbolRepository.m */; }; 24 | E3A96E6D21A7982500CC6B73 /* CSNSymbolMasterItem.m in Sources */ = {isa = PBXBuildFile; fileRef = E3E49E5521A6DA9C001BBB19 /* CSNSymbolMasterItem.m */; }; 25 | E3E49E5221A6D778001BBB19 /* CSNSymbolRepository.h in Headers */ = {isa = PBXBuildFile; fileRef = E3E49E5021A6D778001BBB19 /* CSNSymbolRepository.h */; }; 26 | E3E49E5321A6D778001BBB19 /* CSNSymbolRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = E3E49E5121A6D778001BBB19 /* CSNSymbolRepository.m */; }; 27 | E3E49E5621A6DA9C001BBB19 /* CSNSymbolMasterItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E3E49E5421A6DA9C001BBB19 /* CSNSymbolMasterItem.h */; }; 28 | E3E49E5721A6DA9C001BBB19 /* CSNSymbolMasterItem.m in Sources */ = {isa = PBXBuildFile; fileRef = E3E49E5521A6DA9C001BBB19 /* CSNSymbolMasterItem.m */; }; 29 | E3E49E5A21A6DB8A001BBB19 /* CSNNameTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = E3E49E5821A6DB8A001BBB19 /* CSNNameTokenizer.h */; }; 30 | E3E49E5B21A6DB8A001BBB19 /* CSNNameTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = E3E49E5921A6DB8A001BBB19 /* CSNNameTokenizer.m */; }; 31 | E3E49E5C21A6DBEA001BBB19 /* CSNNameTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = E3E49E5921A6DB8A001BBB19 /* CSNNameTokenizer.m */; }; 32 | E3FDBE5621A7BD80004AB3A7 /* CSNFetchResult.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FDBE5421A7BD80004AB3A7 /* CSNFetchResult.h */; }; 33 | E3FDBE5721A7BD80004AB3A7 /* CSNFetchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE5521A7BD80004AB3A7 /* CSNFetchResult.m */; }; 34 | E3FDBE5821A7BD80004AB3A7 /* CSNFetchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE5521A7BD80004AB3A7 /* CSNFetchResult.m */; }; 35 | E3FDBE5B21A7CC99004AB3A7 /* CSNSuggestionsWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FDBE5921A7CC99004AB3A7 /* CSNSuggestionsWindowController.h */; }; 36 | E3FDBE5C21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE5A21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m */; }; 37 | E3FDBE5D21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE5A21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m */; }; 38 | E3FDBE6221A7EA8D004AB3A7 /* CSNRowView.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FDBE6021A7EA8D004AB3A7 /* CSNRowView.h */; }; 39 | E3FDBE6321A7EA8D004AB3A7 /* CSNRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE6121A7EA8D004AB3A7 /* CSNRowView.m */; }; 40 | E3FDBE6721A7EAA5004AB3A7 /* CSNSuggestionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FDBE6521A7EAA5004AB3A7 /* CSNSuggestionCell.h */; }; 41 | E3FDBE6821A7EAA5004AB3A7 /* CSNSuggestionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE6621A7EAA5004AB3A7 /* CSNSuggestionCell.m */; }; 42 | E3FDBE6C21A7EAD9004AB3A7 /* CSNSuggestionsTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FDBE6A21A7EAD9004AB3A7 /* CSNSuggestionsTableView.h */; }; 43 | E3FDBE6D21A7EAD9004AB3A7 /* CSNSuggestionsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE6B21A7EAD9004AB3A7 /* CSNSuggestionsTableView.m */; }; 44 | E3FDBE7121A7EB9D004AB3A7 /* NSColor+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FDBE6F21A7EB9D004AB3A7 /* NSColor+Additions.h */; }; 45 | E3FDBE7221A7EB9D004AB3A7 /* NSColor+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE7021A7EB9D004AB3A7 /* NSColor+Additions.m */; }; 46 | E3FDBE7A21AAA268004AB3A7 /* CSNNameTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E3FDBE7921AAA268004AB3A7 /* CSNNameTokenizerTests.m */; }; 47 | /* End PBXBuildFile section */ 48 | 49 | /* Begin PBXContainerItemProxy section */ 50 | D0FF4A9B21A69229000FA0DC /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = D0FF4A8721A69229000FA0DC /* Project object */; 53 | proxyType = 1; 54 | remoteGlobalIDString = D0FF4A8F21A69229000FA0DC; 55 | remoteInfo = SymbolNameAutocomplete; 56 | }; 57 | /* End PBXContainerItemProxy section */ 58 | 59 | /* Begin PBXFileReference section */ 60 | D0FF4A9021A69229000FA0DC /* SymbolNameAutocomplete.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SymbolNameAutocomplete.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | D0FF4A9321A69229000FA0DC /* SymbolNameAutocomplete.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolNameAutocomplete.h; sourceTree = ""; }; 62 | D0FF4A9421A69229000FA0DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | D0FF4A9921A69229000FA0DC /* SymbolNameAutocompleteTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SymbolNameAutocompleteTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | D0FF4AA021A69229000FA0DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | D0FF4AAA21A692F3000FA0DC /* SymbolNameAutocompletePluginController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolNameAutocompletePluginController.h; sourceTree = ""; }; 66 | D0FF4AAB21A692F3000FA0DC /* SymbolNameAutocompletePluginController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SymbolNameAutocompletePluginController.m; sourceTree = ""; }; 67 | D0FF4AB621A69952000FA0DC /* CSNSuggestionController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNSuggestionController.h; sourceTree = ""; }; 68 | D0FF4AB721A69952000FA0DC /* CSNSuggestionController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSuggestionController.m; sourceTree = ""; }; 69 | D0FF4ABB21A6998B000FA0DC /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 70 | E3A78DDB21AD8A94007228F8 /* CHSheetController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHSheetController.h; sourceTree = ""; }; 71 | E3A78DDC21AD8A94007228F8 /* MSSymbolMaster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSSymbolMaster.h; sourceTree = ""; }; 72 | E3A78DDD21AD8A94007228F8 /* MSCreateSymbolNamingSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSCreateSymbolNamingSheet.h; sourceTree = ""; }; 73 | E3A78DDE21AD8A94007228F8 /* MSDocumentData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSDocumentData.h; sourceTree = ""; }; 74 | E3A78DE321AD8AF8007228F8 /* CHWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHWindowController.h; sourceTree = ""; }; 75 | E3A96E6A21A7980500CC6B73 /* CSNSymbolRepositoryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSymbolRepositoryTests.m; sourceTree = ""; }; 76 | E3E49E5021A6D778001BBB19 /* CSNSymbolRepository.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNSymbolRepository.h; sourceTree = ""; }; 77 | E3E49E5121A6D778001BBB19 /* CSNSymbolRepository.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSymbolRepository.m; sourceTree = ""; }; 78 | E3E49E5421A6DA9C001BBB19 /* CSNSymbolMasterItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNSymbolMasterItem.h; sourceTree = ""; }; 79 | E3E49E5521A6DA9C001BBB19 /* CSNSymbolMasterItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSymbolMasterItem.m; sourceTree = ""; }; 80 | E3E49E5821A6DB8A001BBB19 /* CSNNameTokenizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNNameTokenizer.h; sourceTree = ""; }; 81 | E3E49E5921A6DB8A001BBB19 /* CSNNameTokenizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNNameTokenizer.m; sourceTree = ""; }; 82 | E3FDBE5421A7BD80004AB3A7 /* CSNFetchResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNFetchResult.h; sourceTree = ""; }; 83 | E3FDBE5521A7BD80004AB3A7 /* CSNFetchResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNFetchResult.m; sourceTree = ""; }; 84 | E3FDBE5921A7CC99004AB3A7 /* CSNSuggestionsWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNSuggestionsWindowController.h; sourceTree = ""; }; 85 | E3FDBE5A21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSuggestionsWindowController.m; sourceTree = ""; }; 86 | E3FDBE6021A7EA8D004AB3A7 /* CSNRowView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNRowView.h; sourceTree = ""; }; 87 | E3FDBE6121A7EA8D004AB3A7 /* CSNRowView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNRowView.m; sourceTree = ""; }; 88 | E3FDBE6521A7EAA5004AB3A7 /* CSNSuggestionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNSuggestionCell.h; sourceTree = ""; }; 89 | E3FDBE6621A7EAA5004AB3A7 /* CSNSuggestionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSuggestionCell.m; sourceTree = ""; }; 90 | E3FDBE6A21A7EAD9004AB3A7 /* CSNSuggestionsTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSNSuggestionsTableView.h; sourceTree = ""; }; 91 | E3FDBE6B21A7EAD9004AB3A7 /* CSNSuggestionsTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNSuggestionsTableView.m; sourceTree = ""; }; 92 | E3FDBE6F21A7EB9D004AB3A7 /* NSColor+Additions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSColor+Additions.h"; sourceTree = ""; }; 93 | E3FDBE7021A7EB9D004AB3A7 /* NSColor+Additions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSColor+Additions.m"; sourceTree = ""; }; 94 | E3FDBE7921AAA268004AB3A7 /* CSNNameTokenizerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSNNameTokenizerTests.m; sourceTree = ""; }; 95 | /* End PBXFileReference section */ 96 | 97 | /* Begin PBXFrameworksBuildPhase section */ 98 | D0FF4A8D21A69229000FA0DC /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | D0FF4ABC21A6998B000FA0DC /* AppKit.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | D0FF4A9621A69229000FA0DC /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | D0FF4A9A21A69229000FA0DC /* SymbolNameAutocomplete.framework in Frameworks */, 111 | ); 112 | runOnlyForDeploymentPostprocessing = 0; 113 | }; 114 | /* End PBXFrameworksBuildPhase section */ 115 | 116 | /* Begin PBXGroup section */ 117 | D0FF4A8621A69229000FA0DC = { 118 | isa = PBXGroup; 119 | children = ( 120 | D0FF4A9221A69229000FA0DC /* SymbolNameAutocomplete */, 121 | E3A78DDA21AD8A94007228F8 /* Headers */, 122 | D0FF4A9D21A69229000FA0DC /* SymbolNameAutocompleteTests */, 123 | D0FF4A9121A69229000FA0DC /* Products */, 124 | D0FF4ABA21A6998B000FA0DC /* Frameworks */, 125 | ); 126 | sourceTree = ""; 127 | }; 128 | D0FF4A9121A69229000FA0DC /* Products */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | D0FF4A9021A69229000FA0DC /* SymbolNameAutocomplete.framework */, 132 | D0FF4A9921A69229000FA0DC /* SymbolNameAutocompleteTests.xctest */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | D0FF4A9221A69229000FA0DC /* SymbolNameAutocomplete */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | D0FF4A9421A69229000FA0DC /* Info.plist */, 141 | D0FF4A9321A69229000FA0DC /* SymbolNameAutocomplete.h */, 142 | D0FF4AAA21A692F3000FA0DC /* SymbolNameAutocompletePluginController.h */, 143 | D0FF4AAB21A692F3000FA0DC /* SymbolNameAutocompletePluginController.m */, 144 | D0FF4AB621A69952000FA0DC /* CSNSuggestionController.h */, 145 | D0FF4AB721A69952000FA0DC /* CSNSuggestionController.m */, 146 | E3FDBE5921A7CC99004AB3A7 /* CSNSuggestionsWindowController.h */, 147 | E3FDBE5A21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m */, 148 | E3FDBE7B21AC0D5F004AB3A7 /* Models */, 149 | E3FDBE6E21A7EB65004AB3A7 /* Categories */, 150 | E3FDBE5F21A7EA73004AB3A7 /* Views */, 151 | ); 152 | path = SymbolNameAutocomplete; 153 | sourceTree = ""; 154 | }; 155 | D0FF4A9D21A69229000FA0DC /* SymbolNameAutocompleteTests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | E3FDBE7921AAA268004AB3A7 /* CSNNameTokenizerTests.m */, 159 | E3A96E6A21A7980500CC6B73 /* CSNSymbolRepositoryTests.m */, 160 | D0FF4AA021A69229000FA0DC /* Info.plist */, 161 | ); 162 | path = SymbolNameAutocompleteTests; 163 | sourceTree = ""; 164 | }; 165 | D0FF4ABA21A6998B000FA0DC /* Frameworks */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | D0FF4ABB21A6998B000FA0DC /* AppKit.framework */, 169 | ); 170 | name = Frameworks; 171 | sourceTree = ""; 172 | }; 173 | E3A78DDA21AD8A94007228F8 /* Headers */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | E3A78DDC21AD8A94007228F8 /* MSSymbolMaster.h */, 177 | E3A78DDD21AD8A94007228F8 /* MSCreateSymbolNamingSheet.h */, 178 | E3A78DDE21AD8A94007228F8 /* MSDocumentData.h */, 179 | E3A78DE321AD8AF8007228F8 /* CHWindowController.h */, 180 | E3A78DDB21AD8A94007228F8 /* CHSheetController.h */, 181 | ); 182 | name = Headers; 183 | path = SymbolNameAutocomplete/Headers; 184 | sourceTree = ""; 185 | }; 186 | E3FDBE5F21A7EA73004AB3A7 /* Views */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | E3FDBE6A21A7EAD9004AB3A7 /* CSNSuggestionsTableView.h */, 190 | E3FDBE6B21A7EAD9004AB3A7 /* CSNSuggestionsTableView.m */, 191 | E3FDBE6521A7EAA5004AB3A7 /* CSNSuggestionCell.h */, 192 | E3FDBE6621A7EAA5004AB3A7 /* CSNSuggestionCell.m */, 193 | E3FDBE6021A7EA8D004AB3A7 /* CSNRowView.h */, 194 | E3FDBE6121A7EA8D004AB3A7 /* CSNRowView.m */, 195 | ); 196 | path = Views; 197 | sourceTree = ""; 198 | }; 199 | E3FDBE6E21A7EB65004AB3A7 /* Categories */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | E3FDBE6F21A7EB9D004AB3A7 /* NSColor+Additions.h */, 203 | E3FDBE7021A7EB9D004AB3A7 /* NSColor+Additions.m */, 204 | ); 205 | path = Categories; 206 | sourceTree = ""; 207 | }; 208 | E3FDBE7B21AC0D5F004AB3A7 /* Models */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | E3E49E5021A6D778001BBB19 /* CSNSymbolRepository.h */, 212 | E3E49E5121A6D778001BBB19 /* CSNSymbolRepository.m */, 213 | E3FDBE5421A7BD80004AB3A7 /* CSNFetchResult.h */, 214 | E3FDBE5521A7BD80004AB3A7 /* CSNFetchResult.m */, 215 | E3E49E5421A6DA9C001BBB19 /* CSNSymbolMasterItem.h */, 216 | E3E49E5521A6DA9C001BBB19 /* CSNSymbolMasterItem.m */, 217 | E3E49E5821A6DB8A001BBB19 /* CSNNameTokenizer.h */, 218 | E3E49E5921A6DB8A001BBB19 /* CSNNameTokenizer.m */, 219 | ); 220 | path = Models; 221 | sourceTree = ""; 222 | }; 223 | /* End PBXGroup section */ 224 | 225 | /* Begin PBXHeadersBuildPhase section */ 226 | D0FF4A8B21A69229000FA0DC /* Headers */ = { 227 | isa = PBXHeadersBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | E3FDBE7121A7EB9D004AB3A7 /* NSColor+Additions.h in Headers */, 231 | E3E49E5A21A6DB8A001BBB19 /* CSNNameTokenizer.h in Headers */, 232 | E3A78DDF21AD8A94007228F8 /* CHSheetController.h in Headers */, 233 | D0FF4AAC21A692F3000FA0DC /* SymbolNameAutocompletePluginController.h in Headers */, 234 | E3A78DE121AD8A94007228F8 /* MSCreateSymbolNamingSheet.h in Headers */, 235 | E3FDBE6C21A7EAD9004AB3A7 /* CSNSuggestionsTableView.h in Headers */, 236 | E3E49E5221A6D778001BBB19 /* CSNSymbolRepository.h in Headers */, 237 | E3A78DE421AD8AF8007228F8 /* CHWindowController.h in Headers */, 238 | E3FDBE5B21A7CC99004AB3A7 /* CSNSuggestionsWindowController.h in Headers */, 239 | D0FF4AB821A69952000FA0DC /* CSNSuggestionController.h in Headers */, 240 | E3FDBE6221A7EA8D004AB3A7 /* CSNRowView.h in Headers */, 241 | E3FDBE6721A7EAA5004AB3A7 /* CSNSuggestionCell.h in Headers */, 242 | E3A78DE021AD8A94007228F8 /* MSSymbolMaster.h in Headers */, 243 | E3E49E5621A6DA9C001BBB19 /* CSNSymbolMasterItem.h in Headers */, 244 | D0FF4AA121A69229000FA0DC /* SymbolNameAutocomplete.h in Headers */, 245 | E3FDBE5621A7BD80004AB3A7 /* CSNFetchResult.h in Headers */, 246 | E3A78DE221AD8A94007228F8 /* MSDocumentData.h in Headers */, 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | /* End PBXHeadersBuildPhase section */ 251 | 252 | /* Begin PBXNativeTarget section */ 253 | D0FF4A8F21A69229000FA0DC /* SymbolNameAutocomplete */ = { 254 | isa = PBXNativeTarget; 255 | buildConfigurationList = D0FF4AA421A69229000FA0DC /* Build configuration list for PBXNativeTarget "SymbolNameAutocomplete" */; 256 | buildPhases = ( 257 | D0FF4A8B21A69229000FA0DC /* Headers */, 258 | D0FF4A8C21A69229000FA0DC /* Sources */, 259 | D0FF4A8D21A69229000FA0DC /* Frameworks */, 260 | D0FF4A8E21A69229000FA0DC /* Resources */, 261 | E3695D78222A14E200FBA74E /* Install Plugin */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | ); 267 | name = SymbolNameAutocomplete; 268 | productName = SymbolNameAutocomplete; 269 | productReference = D0FF4A9021A69229000FA0DC /* SymbolNameAutocomplete.framework */; 270 | productType = "com.apple.product-type.framework"; 271 | }; 272 | D0FF4A9821A69229000FA0DC /* SymbolNameAutocompleteTests */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = D0FF4AA721A69229000FA0DC /* Build configuration list for PBXNativeTarget "SymbolNameAutocompleteTests" */; 275 | buildPhases = ( 276 | D0FF4A9521A69229000FA0DC /* Sources */, 277 | D0FF4A9621A69229000FA0DC /* Frameworks */, 278 | D0FF4A9721A69229000FA0DC /* Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | D0FF4A9C21A69229000FA0DC /* PBXTargetDependency */, 284 | ); 285 | name = SymbolNameAutocompleteTests; 286 | productName = SymbolNameAutocompleteTests; 287 | productReference = D0FF4A9921A69229000FA0DC /* SymbolNameAutocompleteTests.xctest */; 288 | productType = "com.apple.product-type.bundle.unit-test"; 289 | }; 290 | /* End PBXNativeTarget section */ 291 | 292 | /* Begin PBXProject section */ 293 | D0FF4A8721A69229000FA0DC /* Project object */ = { 294 | isa = PBXProject; 295 | attributes = { 296 | LastUpgradeCheck = 1010; 297 | ORGANIZATIONNAME = "cyan-stivy.com"; 298 | TargetAttributes = { 299 | D0FF4A8F21A69229000FA0DC = { 300 | CreatedOnToolsVersion = 10.1; 301 | LastSwiftMigration = 1010; 302 | }; 303 | D0FF4A9821A69229000FA0DC = { 304 | CreatedOnToolsVersion = 10.1; 305 | }; 306 | }; 307 | }; 308 | buildConfigurationList = D0FF4A8A21A69229000FA0DC /* Build configuration list for PBXProject "SymbolNameAutocomplete" */; 309 | compatibilityVersion = "Xcode 9.3"; 310 | developmentRegion = en; 311 | hasScannedForEncodings = 0; 312 | knownRegions = ( 313 | en, 314 | ); 315 | mainGroup = D0FF4A8621A69229000FA0DC; 316 | productRefGroup = D0FF4A9121A69229000FA0DC /* Products */; 317 | projectDirPath = ""; 318 | projectRoot = ""; 319 | targets = ( 320 | D0FF4A8F21A69229000FA0DC /* SymbolNameAutocomplete */, 321 | D0FF4A9821A69229000FA0DC /* SymbolNameAutocompleteTests */, 322 | ); 323 | }; 324 | /* End PBXProject section */ 325 | 326 | /* Begin PBXResourcesBuildPhase section */ 327 | D0FF4A8E21A69229000FA0DC /* Resources */ = { 328 | isa = PBXResourcesBuildPhase; 329 | buildActionMask = 2147483647; 330 | files = ( 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | D0FF4A9721A69229000FA0DC /* Resources */ = { 335 | isa = PBXResourcesBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | ); 339 | runOnlyForDeploymentPostprocessing = 0; 340 | }; 341 | /* End PBXResourcesBuildPhase section */ 342 | 343 | /* Begin PBXShellScriptBuildPhase section */ 344 | E3695D78222A14E200FBA74E /* Install Plugin */ = { 345 | isa = PBXShellScriptBuildPhase; 346 | buildActionMask = 2147483647; 347 | files = ( 348 | ); 349 | inputFileListPaths = ( 350 | ); 351 | inputPaths = ( 352 | ); 353 | name = "Install Plugin"; 354 | outputFileListPaths = ( 355 | ); 356 | outputPaths = ( 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | shellPath = /bin/sh; 360 | shellScript = "sh Scripts/Build-Phases/copy_framework.sh\n"; 361 | }; 362 | /* End PBXShellScriptBuildPhase section */ 363 | 364 | /* Begin PBXSourcesBuildPhase section */ 365 | D0FF4A8C21A69229000FA0DC /* Sources */ = { 366 | isa = PBXSourcesBuildPhase; 367 | buildActionMask = 2147483647; 368 | files = ( 369 | E3FDBE5721A7BD80004AB3A7 /* CSNFetchResult.m in Sources */, 370 | D0FF4AB921A69952000FA0DC /* CSNSuggestionController.m in Sources */, 371 | E3E49E5B21A6DB8A001BBB19 /* CSNNameTokenizer.m in Sources */, 372 | E3FDBE5C21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m in Sources */, 373 | E3E49E5721A6DA9C001BBB19 /* CSNSymbolMasterItem.m in Sources */, 374 | D0FF4AAD21A692F3000FA0DC /* SymbolNameAutocompletePluginController.m in Sources */, 375 | E3FDBE6321A7EA8D004AB3A7 /* CSNRowView.m in Sources */, 376 | E3FDBE7221A7EB9D004AB3A7 /* NSColor+Additions.m in Sources */, 377 | E3FDBE6821A7EAA5004AB3A7 /* CSNSuggestionCell.m in Sources */, 378 | E3FDBE6D21A7EAD9004AB3A7 /* CSNSuggestionsTableView.m in Sources */, 379 | E3E49E5321A6D778001BBB19 /* CSNSymbolRepository.m in Sources */, 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | D0FF4A9521A69229000FA0DC /* Sources */ = { 384 | isa = PBXSourcesBuildPhase; 385 | buildActionMask = 2147483647; 386 | files = ( 387 | E3FDBE5821A7BD80004AB3A7 /* CSNFetchResult.m in Sources */, 388 | E3A96E6D21A7982500CC6B73 /* CSNSymbolMasterItem.m in Sources */, 389 | E3A96E6B21A7980500CC6B73 /* CSNSymbolRepositoryTests.m in Sources */, 390 | E3FDBE5D21A7CC99004AB3A7 /* CSNSuggestionsWindowController.m in Sources */, 391 | E3FDBE7A21AAA268004AB3A7 /* CSNNameTokenizerTests.m in Sources */, 392 | E3A96E6C21A7981800CC6B73 /* CSNSymbolRepository.m in Sources */, 393 | E3E49E5C21A6DBEA001BBB19 /* CSNNameTokenizer.m in Sources */, 394 | ); 395 | runOnlyForDeploymentPostprocessing = 0; 396 | }; 397 | /* End PBXSourcesBuildPhase section */ 398 | 399 | /* Begin PBXTargetDependency section */ 400 | D0FF4A9C21A69229000FA0DC /* PBXTargetDependency */ = { 401 | isa = PBXTargetDependency; 402 | target = D0FF4A8F21A69229000FA0DC /* SymbolNameAutocomplete */; 403 | targetProxy = D0FF4A9B21A69229000FA0DC /* PBXContainerItemProxy */; 404 | }; 405 | /* End PBXTargetDependency section */ 406 | 407 | /* Begin XCBuildConfiguration section */ 408 | D0FF4AA221A69229000FA0DC /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | ALWAYS_SEARCH_USER_PATHS = NO; 412 | CLANG_ANALYZER_NONNULL = YES; 413 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 414 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 415 | CLANG_CXX_LIBRARY = "libc++"; 416 | CLANG_ENABLE_MODULES = YES; 417 | CLANG_ENABLE_OBJC_ARC = YES; 418 | CLANG_ENABLE_OBJC_WEAK = YES; 419 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 420 | CLANG_WARN_BOOL_CONVERSION = YES; 421 | CLANG_WARN_COMMA = YES; 422 | CLANG_WARN_CONSTANT_CONVERSION = YES; 423 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 424 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 425 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 426 | CLANG_WARN_EMPTY_BODY = YES; 427 | CLANG_WARN_ENUM_CONVERSION = YES; 428 | CLANG_WARN_INFINITE_RECURSION = YES; 429 | CLANG_WARN_INT_CONVERSION = YES; 430 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 431 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 432 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 434 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 435 | CLANG_WARN_STRICT_PROTOTYPES = YES; 436 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 437 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 438 | CLANG_WARN_UNREACHABLE_CODE = YES; 439 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 440 | CODE_SIGN_IDENTITY = "Mac Developer"; 441 | COPY_PHASE_STRIP = NO; 442 | CURRENT_PROJECT_VERSION = 1; 443 | DEBUG_INFORMATION_FORMAT = dwarf; 444 | ENABLE_STRICT_OBJC_MSGSEND = YES; 445 | ENABLE_TESTABILITY = YES; 446 | GCC_C_LANGUAGE_STANDARD = gnu11; 447 | GCC_DYNAMIC_NO_PIC = NO; 448 | GCC_NO_COMMON_BLOCKS = YES; 449 | GCC_OPTIMIZATION_LEVEL = 0; 450 | GCC_PREPROCESSOR_DEFINITIONS = ( 451 | "DEBUG=1", 452 | "$(inherited)", 453 | ); 454 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 455 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 456 | GCC_WARN_UNDECLARED_SELECTOR = YES; 457 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 458 | GCC_WARN_UNUSED_FUNCTION = YES; 459 | GCC_WARN_UNUSED_VARIABLE = YES; 460 | MACOSX_DEPLOYMENT_TARGET = 10.13; 461 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 462 | MTL_FAST_MATH = YES; 463 | ONLY_ACTIVE_ARCH = YES; 464 | SDKROOT = macosx; 465 | VERSIONING_SYSTEM = "apple-generic"; 466 | VERSION_INFO_PREFIX = ""; 467 | }; 468 | name = Debug; 469 | }; 470 | D0FF4AA321A69229000FA0DC /* Release */ = { 471 | isa = XCBuildConfiguration; 472 | buildSettings = { 473 | ALWAYS_SEARCH_USER_PATHS = NO; 474 | CLANG_ANALYZER_NONNULL = YES; 475 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 476 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 477 | CLANG_CXX_LIBRARY = "libc++"; 478 | CLANG_ENABLE_MODULES = YES; 479 | CLANG_ENABLE_OBJC_ARC = YES; 480 | CLANG_ENABLE_OBJC_WEAK = YES; 481 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 482 | CLANG_WARN_BOOL_CONVERSION = YES; 483 | CLANG_WARN_COMMA = YES; 484 | CLANG_WARN_CONSTANT_CONVERSION = YES; 485 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 486 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 487 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 488 | CLANG_WARN_EMPTY_BODY = YES; 489 | CLANG_WARN_ENUM_CONVERSION = YES; 490 | CLANG_WARN_INFINITE_RECURSION = YES; 491 | CLANG_WARN_INT_CONVERSION = YES; 492 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 493 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 494 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 495 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 496 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 497 | CLANG_WARN_STRICT_PROTOTYPES = YES; 498 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 499 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 500 | CLANG_WARN_UNREACHABLE_CODE = YES; 501 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 502 | CODE_SIGN_IDENTITY = "Mac Developer"; 503 | COPY_PHASE_STRIP = NO; 504 | CURRENT_PROJECT_VERSION = 1; 505 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 506 | ENABLE_NS_ASSERTIONS = NO; 507 | ENABLE_STRICT_OBJC_MSGSEND = YES; 508 | GCC_C_LANGUAGE_STANDARD = gnu11; 509 | GCC_NO_COMMON_BLOCKS = YES; 510 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 511 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 512 | GCC_WARN_UNDECLARED_SELECTOR = YES; 513 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 514 | GCC_WARN_UNUSED_FUNCTION = YES; 515 | GCC_WARN_UNUSED_VARIABLE = YES; 516 | MACOSX_DEPLOYMENT_TARGET = 10.13; 517 | MTL_ENABLE_DEBUG_INFO = NO; 518 | MTL_FAST_MATH = YES; 519 | SDKROOT = macosx; 520 | VERSIONING_SYSTEM = "apple-generic"; 521 | VERSION_INFO_PREFIX = ""; 522 | }; 523 | name = Release; 524 | }; 525 | D0FF4AA521A69229000FA0DC /* Debug */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | CLANG_ENABLE_MODULES = YES; 529 | CODE_SIGN_IDENTITY = "Developer ID Application"; 530 | CODE_SIGN_STYLE = Manual; 531 | COMBINE_HIDPI_IMAGES = YES; 532 | CURRENT_PROJECT_VERSION = 3; 533 | DEFINES_MODULE = YES; 534 | DEVELOPMENT_TEAM = P35U7ALH46; 535 | DYLIB_COMPATIBILITY_VERSION = 1; 536 | DYLIB_CURRENT_VERSION = 1; 537 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 538 | FRAMEWORK_VERSION = A; 539 | INFOPLIST_FILE = SymbolNameAutocomplete/Info.plist; 540 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 541 | LD_RUNPATH_SEARCH_PATHS = ( 542 | "$(inherited)", 543 | "@executable_path/../Frameworks", 544 | "@loader_path/Frameworks", 545 | ); 546 | MARKETING_VERSION = 0.5.5; 547 | PRODUCT_BUNDLE_IDENTIFIER = "net.cyan-stivy.sketchPlugin.symbol-name-autocomplete"; 548 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 549 | PROVISIONING_PROFILE_SPECIFIER = ""; 550 | SKIP_INSTALL = YES; 551 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 552 | SWIFT_VERSION = 4.2; 553 | }; 554 | name = Debug; 555 | }; 556 | D0FF4AA621A69229000FA0DC /* Release */ = { 557 | isa = XCBuildConfiguration; 558 | buildSettings = { 559 | CLANG_ENABLE_MODULES = YES; 560 | CODE_SIGN_IDENTITY = "Developer ID Application"; 561 | CODE_SIGN_STYLE = Manual; 562 | COMBINE_HIDPI_IMAGES = YES; 563 | CURRENT_PROJECT_VERSION = 3; 564 | DEFINES_MODULE = YES; 565 | DEVELOPMENT_TEAM = P35U7ALH46; 566 | DYLIB_COMPATIBILITY_VERSION = 1; 567 | DYLIB_CURRENT_VERSION = 1; 568 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 569 | FRAMEWORK_VERSION = A; 570 | INFOPLIST_FILE = SymbolNameAutocomplete/Info.plist; 571 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 572 | LD_RUNPATH_SEARCH_PATHS = ( 573 | "$(inherited)", 574 | "@executable_path/../Frameworks", 575 | "@loader_path/Frameworks", 576 | ); 577 | MARKETING_VERSION = 0.5.5; 578 | OTHER_CODE_SIGN_FLAGS = "--timestamp"; 579 | PRODUCT_BUNDLE_IDENTIFIER = "net.cyan-stivy.sketchPlugin.symbol-name-autocomplete"; 580 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 581 | PROVISIONING_PROFILE_SPECIFIER = ""; 582 | SKIP_INSTALL = YES; 583 | SWIFT_VERSION = 4.2; 584 | }; 585 | name = Release; 586 | }; 587 | D0FF4AA821A69229000FA0DC /* Debug */ = { 588 | isa = XCBuildConfiguration; 589 | buildSettings = { 590 | CODE_SIGN_IDENTITY = "Mac Developer"; 591 | CODE_SIGN_STYLE = Automatic; 592 | COMBINE_HIDPI_IMAGES = YES; 593 | DEVELOPMENT_TEAM = P35U7ALH46; 594 | INFOPLIST_FILE = SymbolNameAutocompleteTests/Info.plist; 595 | LD_RUNPATH_SEARCH_PATHS = ( 596 | "$(inherited)", 597 | "@executable_path/../Frameworks", 598 | "@loader_path/../Frameworks", 599 | ); 600 | PRODUCT_BUNDLE_IDENTIFIER = "com.cyan-stivy.SymbolNameAutocompleteTests"; 601 | PRODUCT_NAME = "$(TARGET_NAME)"; 602 | PROVISIONING_PROFILE_SPECIFIER = ""; 603 | }; 604 | name = Debug; 605 | }; 606 | D0FF4AA921A69229000FA0DC /* Release */ = { 607 | isa = XCBuildConfiguration; 608 | buildSettings = { 609 | CODE_SIGN_IDENTITY = "Mac Developer"; 610 | CODE_SIGN_STYLE = Automatic; 611 | COMBINE_HIDPI_IMAGES = YES; 612 | DEVELOPMENT_TEAM = P35U7ALH46; 613 | INFOPLIST_FILE = SymbolNameAutocompleteTests/Info.plist; 614 | LD_RUNPATH_SEARCH_PATHS = ( 615 | "$(inherited)", 616 | "@executable_path/../Frameworks", 617 | "@loader_path/../Frameworks", 618 | ); 619 | PRODUCT_BUNDLE_IDENTIFIER = "com.cyan-stivy.SymbolNameAutocompleteTests"; 620 | PRODUCT_NAME = "$(TARGET_NAME)"; 621 | PROVISIONING_PROFILE_SPECIFIER = ""; 622 | }; 623 | name = Release; 624 | }; 625 | /* End XCBuildConfiguration section */ 626 | 627 | /* Begin XCConfigurationList section */ 628 | D0FF4A8A21A69229000FA0DC /* Build configuration list for PBXProject "SymbolNameAutocomplete" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | D0FF4AA221A69229000FA0DC /* Debug */, 632 | D0FF4AA321A69229000FA0DC /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | D0FF4AA421A69229000FA0DC /* Build configuration list for PBXNativeTarget "SymbolNameAutocomplete" */ = { 638 | isa = XCConfigurationList; 639 | buildConfigurations = ( 640 | D0FF4AA521A69229000FA0DC /* Debug */, 641 | D0FF4AA621A69229000FA0DC /* Release */, 642 | ); 643 | defaultConfigurationIsVisible = 0; 644 | defaultConfigurationName = Release; 645 | }; 646 | D0FF4AA721A69229000FA0DC /* Build configuration list for PBXNativeTarget "SymbolNameAutocompleteTests" */ = { 647 | isa = XCConfigurationList; 648 | buildConfigurations = ( 649 | D0FF4AA821A69229000FA0DC /* Debug */, 650 | D0FF4AA921A69229000FA0DC /* Release */, 651 | ); 652 | defaultConfigurationIsVisible = 0; 653 | defaultConfigurationName = Release; 654 | }; 655 | /* End XCConfigurationList section */ 656 | }; 657 | rootObject = D0FF4A8721A69229000FA0DC /* Project object */; 658 | } 659 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/AnalyticsTrackingID.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnalyticsTrackingID.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2019/03/02. 6 | // Copyright © 2019 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #ifndef AnalyticsTrackingID_h 10 | #define AnalyticsTrackingID_h 11 | 12 | #define TRACKING_ID @"UA-1908606-9" 13 | 14 | #endif /* AnalyticsTrackingID_h */ 15 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/CSNSuggestionController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionController.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class CSNSymbolRepository; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CSNSuggestionController : NSObject 17 | 18 | @property (nonatomic, strong) NSWindow *window; 19 | @property (nonatomic, weak) iddelegate; 20 | @property (nonatomic, weak) idtextFieldProxyDelegate; 21 | @property (nonatomic, strong) CSNSymbolRepository *symbolRepository; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/CSNSuggestionController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionController.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNSuggestionController.h" 10 | #import "CSNFetchResult.h" 11 | #import "CSNNameTokenizer.h" 12 | #import "CSNSymbolRepository.h" 13 | #import "CSNSuggestionsWindowController.h" 14 | 15 | @interface CSNSuggestionController () 16 | @property (nonatomic, weak) NSText *fieldEditor; 17 | @property (nonatomic, strong) CSNSuggestionsWindowController *windowController; 18 | @property (nonatomic, assign) BOOL skipUpdatingFieldEditor; 19 | @end 20 | 21 | @implementation CSNSuggestionController 22 | 23 | - (void)dealloc 24 | { 25 | self.delegate = nil; 26 | } 27 | 28 | /* Update the field editor with a suggested string. The additional suggested characters are auto selected. 29 | */ 30 | - (void)updateFieldEditor:(NSText *)fieldEditor withSuggestion:(NSString *)suggestion 31 | { 32 | if (suggestion == nil) { 33 | return ; 34 | } 35 | 36 | NSRange selection = NSMakeRange([fieldEditor selectedRange].location, [suggestion length]); 37 | [fieldEditor setString:suggestion]; 38 | [fieldEditor setSelectedRange:selection]; 39 | } 40 | 41 | - (void)updateSuggestionsFromControl:(NSControl *)control { 42 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [control debugDescription]); 43 | self.fieldEditor = [self.window fieldEditor:NO forObject:control]; 44 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [self.fieldEditor debugDescription]); 45 | if (self.fieldEditor) { 46 | // Only use the text up to the caret position 47 | NSRange selection = [self.fieldEditor selectedRange]; 48 | NSString *text = [[self.fieldEditor string] substringToIndex:selection.location]; 49 | // NSLog(@"👺 %s %@ '%@'", __PRETTY_FUNCTION__, NSStringFromRange(selection), text); 50 | 51 | if (text == nil || [text length] == 0) { 52 | // NSLog(@"👺 %s search text is blank or nil", __PRETTY_FUNCTION__); 53 | self.skipUpdatingFieldEditor = NO; 54 | return ; 55 | } 56 | 57 | CSNFetchResult *result = [self.symbolRepository fetchItemsByString:text]; 58 | 59 | if (result == nil) { 60 | // NSLog(@"👺 %s not matched any name", __PRETTY_FUNCTION__); 61 | [self.windowController cancelSuggestions]; 62 | self.skipUpdatingFieldEditor = NO; 63 | return ; 64 | } 65 | 66 | NSArray *names = [result tokenStringUpToBottomLevel]; 67 | 68 | // for (NSString *name in names) { 69 | // NSLog(@"👺 %s related name is '%@'", __PRETTY_FUNCTION__, name); 70 | // } 71 | 72 | if (!self.skipUpdatingFieldEditor) { 73 | [self.windowController presentWithSuggestions:names positioningTextView:(NSView *)control]; 74 | } else { 75 | // NSLog(@"👺 %s cancel suggestions cause skipUpdatingFieldEditor is '%@'", __PRETTY_FUNCTION__, [NSNumber numberWithBool:self.skipUpdatingFieldEditor]); 76 | [self.windowController cancelSuggestions]; 77 | } 78 | 79 | self.skipUpdatingFieldEditor = NO; 80 | } 81 | } 82 | 83 | - (NSRange)selectedRangeFromFieldEditor 84 | { 85 | if (self.fieldEditor != nil) { 86 | // Only use the text up to the caret position 87 | return [self.fieldEditor selectedRange]; 88 | } else { 89 | return NSMakeRange(0, 0); 90 | } 91 | } 92 | 93 | - (void)deleteSuggestedTextFromFieldEditor 94 | { 95 | if (self.fieldEditor == nil) { 96 | return ; 97 | } 98 | NSRange selection = [self.fieldEditor selectedRange]; 99 | NSString *text = [[self.fieldEditor string] substringToIndex:selection.location]; 100 | [self.fieldEditor setString:text]; 101 | } 102 | 103 | #pragma mark - CSNSuggestionWindowControllerDelegate 104 | 105 | - (void)suggestionWindowController:(CSNSuggestionsWindowController *)suggestionWindowController didHighlightSuggestion:(NSString *)suggestion 106 | { 107 | // NSLog(@"👺 %s update TextField with '%@'", __PRETTY_FUNCTION__, suggestion); 108 | [self updateFieldEditor:self.fieldEditor withSuggestion:suggestion]; 109 | } 110 | 111 | - (void)suggestionWindowController:(CSNSuggestionsWindowController *)suggestionsWindowController didSelectSuggestion:(NSString *)suggestion 112 | { 113 | [self updateFieldEditor:self.fieldEditor withSuggestion:suggestion]; 114 | NSRange selection = NSMakeRange([self.fieldEditor string].length, 0); 115 | [self.fieldEditor setSelectedRange:selection]; 116 | [self.windowController cancelSuggestions]; 117 | } 118 | 119 | #pragma mark - 120 | #pragma mark Delegate 121 | 122 | - (void)controlTextDidBeginEditing:(NSNotification *)notification 123 | { 124 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [notification debugDescription]); 125 | 126 | if (!self.windowController) { 127 | self.windowController = [[CSNSuggestionsWindowController alloc] init]; 128 | self.windowController.delegate = self; 129 | } 130 | 131 | self.fieldEditor = [self.window fieldEditor:NO forObject:notification.object]; 132 | 133 | if ([_textFieldProxyDelegate respondsToSelector:@selector(controlTextDidBeginEditing:)]) { 134 | [_textFieldProxyDelegate controlTextDidBeginEditing:notification]; 135 | } 136 | } 137 | 138 | - (void)controlTextDidChange:(NSNotification *)notification 139 | { 140 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [notification debugDescription]); 141 | [self updateSuggestionsFromControl:notification.object]; 142 | 143 | if ([_textFieldProxyDelegate respondsToSelector:@selector(controlTextDidChange:)]) { 144 | [_textFieldProxyDelegate controlTextDidChange:notification]; 145 | } 146 | } 147 | 148 | - (void)controlTextDidEndEditing:(NSNotification *)notification 149 | { 150 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [notification debugDescription]); 151 | 152 | [self.windowController cancelSuggestions]; 153 | self.windowController = nil; 154 | 155 | if ([_textFieldProxyDelegate respondsToSelector:@selector(controlTextDidEndEditing:)]) { 156 | [_textFieldProxyDelegate controlTextDidEndEditing:notification]; 157 | } 158 | } 159 | 160 | - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector 161 | { 162 | // NSLog(@"👺 %s selector is '%@'", __PRETTY_FUNCTION__, NSStringFromSelector(commandSelector)); 163 | if (commandSelector == @selector(moveUp:)) { 164 | // Move up in the suggested selections list 165 | [self.windowController moveUp:textView]; 166 | return YES; 167 | } 168 | 169 | if (commandSelector == @selector(moveDown:)) { 170 | // shows all possible suggestions if suggestions list is not visible 171 | if ([self.windowController.window isVisible] == NO) { 172 | if (self.fieldEditor != nil) { 173 | NSString *text = [self.fieldEditor string]; 174 | CSNFetchResult *result = [self.symbolRepository listUpItemsUsingString:text]; 175 | NSArray *suggestions = nil; 176 | if ([result isTokenEndWithDelimeterAtBottomLevel]) { 177 | suggestions = [result tokenStringUpToLevel:result.bottomLevel + 1 unique:YES]; 178 | } else { 179 | suggestions = [result tokenStringUpToBottomLevel]; 180 | } 181 | 182 | if ([suggestions count] > 0) { 183 | [self.windowController presentWithSuggestions:suggestions positioningTextView:control]; 184 | return YES; 185 | } 186 | } 187 | } 188 | 189 | // Move down in the suggested selections list 190 | [self.windowController moveDown:textView]; 191 | return YES; 192 | } 193 | 194 | if (commandSelector == @selector(deleteForward:) || commandSelector == @selector(deleteBackward:)) { 195 | /* The user is deleting the highlighted portion of the suggestion or more. Return NO so that the field editor performs the deletion. The field editor will then call -controlTextDidChange:. We don't want to provide a new set of suggestions as that will put back the characters the user just deleted. Instead, set skipNextSuggestion to YES which will cause -controlTextDidChange: to cancel the suggestions window. (see -controlTextDidChange: above) 196 | */ 197 | 198 | if (self.fieldEditor != nil) { 199 | NSRange selection = [self.fieldEditor selectedRange]; 200 | NSString *text = [[self.fieldEditor string] substringToIndex:selection.location]; 201 | // NSLog(@"👺 %s %@ '%@'", __PRETTY_FUNCTION__, NSStringFromRange(selection), text); 202 | if ([text length] > 0) { 203 | self.skipUpdatingFieldEditor = YES; 204 | } else { 205 | self.skipUpdatingFieldEditor = NO; 206 | } 207 | } 208 | 209 | 210 | return NO; 211 | } 212 | 213 | // `ESC` key 214 | if (commandSelector == @selector(cancelOperation:)) { 215 | // hide suggestions and remove suggeestion string if sugessions is visible. 216 | if ([self.windowController.window isVisible]) { 217 | [self deleteSuggestedTextFromFieldEditor]; 218 | [self.windowController cancelSuggestions]; 219 | return YES; 220 | } else { 221 | return NO; 222 | } 223 | } 224 | 225 | if (commandSelector == @selector(complete:)) { 226 | // The user has pressed the key combination for auto completion. AppKit has a built in auto completion. By overriding this command we prevent AppKit's auto completion and can respond to the user's intention by showing or cancelling our custom suggestions window. 227 | if ([self.windowController.window isVisible]) { 228 | [self.windowController cancelSuggestions]; 229 | } else { 230 | [self updateSuggestionsFromControl:control]; 231 | } 232 | 233 | return YES; 234 | } 235 | 236 | if ( 237 | commandSelector == @selector(insertTab:) || 238 | commandSelector == @selector(insertNewline:) || 239 | commandSelector == @selector(insertNewlineIgnoringFieldEditor:) || 240 | commandSelector == @selector(insertLineBreak:) 241 | ) { 242 | 243 | if ([self.windowController.window isVisible]) { 244 | #pragma clang diagnostic push 245 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 246 | [self.windowController performSelector:commandSelector withObject:textView]; 247 | #pragma clang diagnostic pop 248 | 249 | return YES; 250 | } 251 | 252 | if (self.fieldEditor) { 253 | NSRange selection = [self.fieldEditor selectedRange]; 254 | NSString *text = [[self.fieldEditor string] substringToIndex:selection.location]; 255 | NSLog(@"👺 %s %@ '%@'", __PRETTY_FUNCTION__, NSStringFromRange(selection), text); 256 | 257 | if (selection.length == 0) { 258 | // act default behavior if selection is none. 259 | return NO; 260 | } else { 261 | // let caret moves to the end of line if selection is exists. 262 | NSRange selection = NSMakeRange([self.fieldEditor string].length, 0); 263 | [self.fieldEditor setSelectedRange:selection]; 264 | return YES; 265 | } 266 | } 267 | return YES; 268 | } 269 | 270 | // This is a command that we don't specifically handle, let the field editor do the appropriate thing. 271 | return NO; 272 | } 273 | 274 | #pragma mark - 275 | #pragma mark Method Forwarding 276 | 277 | - (BOOL)respondsToSelector:(SEL)aSelector 278 | { 279 | if ([super respondsToSelector:aSelector]) { 280 | return YES; 281 | } 282 | 283 | if ([self.textFieldProxyDelegate respondsToSelector:aSelector]) { 284 | return YES; 285 | } 286 | 287 | 288 | return NO; 289 | } 290 | 291 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector 292 | { 293 | NSMethodSignature *signature = [super methodSignatureForSelector:selector]; 294 | if (!signature) { 295 | if ([_textFieldProxyDelegate respondsToSelector:selector]) { 296 | return [(NSObject *)_textFieldProxyDelegate methodSignatureForSelector:selector]; 297 | } 298 | } 299 | return signature; 300 | } 301 | 302 | - (void)forwardInvocation:(NSInvocation*)invocation 303 | { 304 | if ([_textFieldProxyDelegate respondsToSelector:[invocation selector]]) { 305 | [invocation invokeWithTarget:_textFieldProxyDelegate]; 306 | } 307 | } 308 | 309 | @end 310 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/CSNSuggestionsWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionsWindowController.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol CSNSuggestionsWindowControllerDelegate; 14 | 15 | @interface CSNSuggestionsWindowController : NSWindowController 16 | 17 | @property (nonatomic, weak) id delegate; 18 | 19 | - (void)presentWithSuggestions:(NSArray *)suggestions positioningTextView:(NSView *)positioningTextView; 20 | - (void)cancelSuggestions; 21 | 22 | @end 23 | 24 | @protocol CSNSuggestionsWindowControllerDelegate 25 | 26 | - (void)suggestionWindowController:(CSNSuggestionsWindowController *)suggestionWindowController didHighlightSuggestion:(NSString *)suggestion; 27 | - (void)suggestionWindowController:(CSNSuggestionsWindowController *)suggestionWindowController didSelectSuggestion:(NSString *)suggestion; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/CSNSuggestionsWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionsWindowController.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNSuggestionsWindowController.h" 10 | #import "CSNSuggestionsTableView.h" 11 | #import "NSColor+Additions.h" 12 | #import "CSNSuggestionCell.h" 13 | #import "CSNRowView.h" 14 | 15 | static const CGFloat CSNSuggestionWindowControllerContentViewCornerRadius = 3.0f; 16 | static const CGFloat CSNSuggestionWindowControllerMargin = 8.0f; 17 | static const NSSize CSNSuggestionWindowControllerMaximumWindowSize = {.width = 190.0f, .height = 208.0f}; 18 | 19 | @interface CSNSuggestionsWindowController () 20 | @property (nonatomic, copy) NSArray *suggestions; 21 | @property (nonatomic, strong) CSNSuggestionsTableView *tableView; 22 | @end 23 | 24 | @implementation CSNSuggestionsWindowController 25 | 26 | - (instancetype)init 27 | { 28 | self = [super initWithWindow:nil]; 29 | if (!self) { 30 | return nil; 31 | } 32 | 33 | NSView *contentView = [[NSView alloc] init]; 34 | contentView.wantsLayer = YES; 35 | contentView.layer.cornerRadius = CSNSuggestionWindowControllerContentViewCornerRadius; 36 | 37 | self.tableView = [[CSNSuggestionsTableView alloc] init]; 38 | self.tableView.headerView = nil; 39 | self.tableView.intercellSpacing = NSZeroSize; 40 | self.tableView.delegate = self; 41 | self.tableView.dataSource = self; 42 | self.tableView.allowsEmptySelection = NO; 43 | 44 | NSColor *tableViewBackgroundColor = [NSColor csn_backgroundColor]; 45 | if (tableViewBackgroundColor) { 46 | self.tableView.backgroundColor = tableViewBackgroundColor; 47 | } 48 | 49 | NSScrollView *scrollView = [[NSScrollView alloc] init]; 50 | scrollView.documentView = self.tableView; 51 | 52 | [contentView addSubview:scrollView]; 53 | 54 | contentView.translatesAutoresizingMaskIntoConstraints = NO; 55 | scrollView.translatesAutoresizingMaskIntoConstraints = NO; 56 | 57 | [NSLayoutConstraint activateConstraints:@[ 58 | [scrollView.topAnchor constraintEqualToAnchor:contentView.topAnchor], 59 | [scrollView.leftAnchor constraintEqualToAnchor:contentView.leftAnchor], 60 | [scrollView.rightAnchor constraintEqualToAnchor:contentView.rightAnchor], 61 | [scrollView.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor] 62 | ]]; 63 | 64 | NSTableColumn *column = [[NSTableColumn alloc] init]; 65 | column.resizingMask = NSTableColumnAutoresizingMask; 66 | [self.tableView addTableColumn:column]; 67 | 68 | NSWindow *window = [[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO]; 69 | window.titleVisibility = NSWindowTitleHidden; 70 | window.hasShadow = YES; 71 | window.opaque = NO; 72 | window.backgroundColor = [NSColor clearColor]; 73 | window.contentView = contentView; 74 | 75 | self.window = window; 76 | 77 | return self; 78 | } 79 | 80 | - (void)dealloc 81 | { 82 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 83 | self.delegate = nil; 84 | } 85 | 86 | - (void)windowDidLoad 87 | { 88 | [super windowDidLoad]; 89 | 90 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 91 | } 92 | 93 | #pragma mark - Public 94 | 95 | - (void)presentWithSuggestions:(NSArray *)suggestions positioningTextView:(NSView *)positioningTextView 96 | { 97 | self.suggestions = suggestions; 98 | 99 | [self.tableView reloadData]; 100 | 101 | if (![self adjustFrameWithPositioningTextView:positioningTextView]) { 102 | return; 103 | } 104 | 105 | if (self.window.isVisible == NO) { 106 | [positioningTextView.window addChildWindow:self.window ordered:NSWindowAbove]; 107 | positioningTextView.postsFrameChangedNotifications = YES; 108 | [[NSNotificationCenter defaultCenter] addObserver:self 109 | selector:@selector(positioningTextViewFrameDidChange:) 110 | name:NSViewFrameDidChangeNotification 111 | object:positioningTextView]; 112 | [[NSNotificationCenter defaultCenter] addObserver:self 113 | selector:@selector(parentWindowDidResignKey:) 114 | name:NSWindowDidResignKeyNotification 115 | object:positioningTextView.window]; 116 | } 117 | } 118 | 119 | - (void)cancelSuggestions 120 | { 121 | if (self.window.isVisible == NO) { 122 | return; 123 | } 124 | 125 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 126 | 127 | [self.window.parentWindow removeChildWindow:self.window]; 128 | [self.window orderOut:nil]; 129 | } 130 | 131 | - (BOOL)adjustFrameWithPositioningTextView:(NSView *)positioningTextView 132 | { 133 | if (self.window == nil || positioningTextView.superview == nil || positioningTextView.window == nil) { 134 | return NO; 135 | } 136 | 137 | CGFloat windowHeight = MIN(self.suggestions.count * CSNSuggestionCell.height + 20, CSNSuggestionWindowControllerMaximumWindowSize.height); 138 | 139 | NSRect positioningTextViewRect = positioningTextView.frame; 140 | NSRect rect = [positioningTextView.window convertRectToScreen:positioningTextViewRect]; 141 | 142 | rect.origin.y = rect.origin.y - windowHeight - CSNSuggestionWindowControllerMargin; 143 | rect.size.width = positioningTextView.frame.size.width; 144 | rect.size.height = windowHeight; 145 | 146 | [self.window setFrame:rect display:NO]; 147 | 148 | return YES; 149 | } 150 | 151 | - (void)selectRowAtIndex:(NSInteger)index 152 | { 153 | if (self.suggestions.count == 0) { 154 | return; 155 | } 156 | 157 | NSInteger adjustedIndex = MAX(0, MIN(index, self.suggestions.count - 1)); 158 | 159 | [self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:adjustedIndex] byExtendingSelection:NO]; 160 | [self.tableView scrollRowToVisible:adjustedIndex]; 161 | [self.delegate suggestionWindowController:self didHighlightSuggestion:self.suggestions[adjustedIndex]]; 162 | } 163 | 164 | #pragma mark - NSTableViewDataSource 165 | 166 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView 167 | { 168 | return self.suggestions.count; 169 | } 170 | 171 | #pragma mark - ZPLFocusTableViewDelegate 172 | 173 | - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 174 | { 175 | CSNSuggestionCell *cell = [tableView makeViewWithIdentifier:[CSNSuggestionCell reuseIdentifier] owner:self]; 176 | if (!cell) { 177 | cell = [[CSNSuggestionCell alloc] init]; 178 | } 179 | 180 | cell.suggestion = self.suggestions[row]; 181 | 182 | return cell; 183 | } 184 | 185 | - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row 186 | { 187 | return [CSNSuggestionCell height]; 188 | } 189 | 190 | - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row 191 | { 192 | return [[CSNRowView alloc] init]; 193 | } 194 | 195 | - (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row 196 | { 197 | return YES; 198 | } 199 | 200 | - (void)tableView:(NSTableView *)tableView didClickRow:(NSInteger)row 201 | { 202 | [self.delegate suggestionWindowController:self didSelectSuggestion:self.suggestions[row]]; 203 | } 204 | 205 | #pragma mark - Notifications 206 | 207 | - (void)positioningTextViewFrameDidChange:(NSNotification *)notification 208 | { 209 | NSTextView *positioningTextView = notification.object; 210 | if (!positioningTextView) { 211 | return; 212 | } 213 | 214 | [self adjustFrameWithPositioningTextView:positioningTextView]; 215 | } 216 | 217 | - (void)parentWindowDidResignKey:(NSNotification *)notification 218 | { 219 | [self cancelSuggestions]; 220 | } 221 | 222 | #pragma mark - Keyboard Tracking 223 | 224 | /* move the selection up and send action. 225 | */ 226 | - (void)moveUp:(id)sender 227 | { 228 | NSInteger row = MAX(self.tableView.selectedRow - 1, 0); 229 | [self selectRowAtIndex:row]; 230 | } 231 | 232 | /* move the selection down and send action. 233 | */ 234 | - (void)moveDown:(id)sender 235 | { 236 | NSInteger lastRow = self.suggestions.count - 1; 237 | NSInteger row = MIN(self.tableView.selectedRow + 1, lastRow); 238 | [self selectRowAtIndex:row]; 239 | } 240 | 241 | - (void)insertTab:(id)sender 242 | { 243 | [self.delegate suggestionWindowController:self didSelectSuggestion:self.suggestions[self.tableView.selectedRow]]; 244 | } 245 | 246 | - (void)insertNewline:(id)sender 247 | { 248 | [self.delegate suggestionWindowController:self didSelectSuggestion:self.suggestions[self.tableView.selectedRow]]; 249 | } 250 | 251 | - (void)insertNewlineIgnoringFieldEditor:(id)sender 252 | { 253 | [self.delegate suggestionWindowController:self didSelectSuggestion:self.suggestions[self.tableView.selectedRow]]; 254 | } 255 | 256 | - (void)insertLineBreak:(id)sender 257 | { 258 | [self.delegate suggestionWindowController:self didSelectSuggestion:self.suggestions[self.tableView.selectedRow]]; 259 | } 260 | 261 | @end 262 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Categories/NSColor+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+Additions.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSColor (Additions) 14 | 15 | + (NSColor *)csn_backgroundColor; 16 | + (NSColor *)csn_selectionColor; 17 | + (NSColor *)csn_textColor; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Categories/NSColor+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+Additions.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "NSColor+Additions.h" 10 | 11 | @implementation NSColor (Additions) 12 | 13 | + (NSColor *)csn_backgroundColor { 14 | return [self controlBackgroundColor]; 15 | } 16 | 17 | + (NSColor *)csn_selectionColor { 18 | if (@available(macOS 10.14, *)) { 19 | return [self controlAccentColor]; 20 | } else { 21 | return [self selectedMenuItemColor]; 22 | } 23 | } 24 | 25 | + (NSColor *)csn_textColor { 26 | return [self controlTextColor]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Headers/CHSheetController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import "CHWindowController.h" 8 | #import 9 | 10 | typedef void(^CDUnknownBlockType)(void); 11 | 12 | @class NSCountedSet, NSString, NSWindow; 13 | 14 | @interface CHSheetController : CHWindowController 15 | { 16 | id _object; 17 | NSWindow *_parentWindow; 18 | NSCountedSet *_selfReferences; 19 | } 20 | 21 | + (id)findSuitableWindowForSheet; 22 | + (id)runForWindow:(id)arg1 withObject:(id)arg2; 23 | + (id)runForWindow:(id)arg1; 24 | @property(retain, nonatomic) NSCountedSet *selfReferences; // @synthesize selfReferences=_selfReferences; 25 | @property(nonatomic) __weak NSWindow *parentWindow; // @synthesize parentWindow=_parentWindow; 26 | @property(retain, nonatomic) id object; // @synthesize object=_object; 27 | 28 | - (void)sheetWillClose; 29 | - (id)_init; 30 | - (id)touchBar:(id)arg1 makeItemForIdentifier:(id)arg2; 31 | - (id)makeTouchBar; 32 | - (SEL)selectorForTouchbarItemIdentifier:(id)arg1; 33 | - (id)touchBarItemIdentifiers; 34 | - (id)windowNibName; 35 | - (void)closeSheet; 36 | - (void)cancel:(id)arg1; 37 | - (void)confirm:(id)arg1; 38 | - (id)run; 39 | - (void)releaseSelf; 40 | - (void)retainSelf; 41 | 42 | @end 43 | 44 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Headers/CHWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import 8 | 9 | @interface CHWindowController : NSWindowController 10 | { 11 | } 12 | 13 | - (void)dealloc; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Headers/MSCreateSymbolNamingSheet.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import "CHSheetController.h" 8 | 9 | @class NSButton, NSTextField; 10 | 11 | @interface MSCreateSymbolNamingSheet : CHSheetController 12 | 13 | @property(retain, nonatomic) NSTextField *symbolPageField; // @synthesize symbolPageField=_symbolPageField; 14 | @property(retain, nonatomic) NSTextField *symbolNameField; // @synthesize symbolNameField=_symbolNameField; 15 | @property(retain, nonatomic) NSButton *confirmButton; // @synthesize confirmButton=_confirmButton; 16 | @property(retain, nonatomic) NSButton *moveSymbolToPageCheckbox; // @synthesize moveSymbolToPageCheckbox=_moveSymbolToPageCheckbox; 17 | 18 | - (void)validateConfirmButton; 19 | - (void)controlTextDidChange:(id)arg1; 20 | - (void)setShouldShowMoveCheckbox:(BOOL)arg1; 21 | - (void)setSuggestedName:(id)arg1; 22 | - (void)setSymbolPageName:(id)arg1; 23 | - (void)confirm:(id)arg1; 24 | - (void)awakeFromNib; 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Headers/MSDocumentData.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import 8 | 9 | @interface MSDocumentData : NSObject 10 | 11 | @property(readonly, nonatomic) NSDictionary *symbolMap; // @synthesize symbolMap=_symbolMap; 12 | 13 | - (void)purgeForeignSymbols; 14 | - (id)symbolsReferencedBySymbolInstances; 15 | - (id)symbolsReferencedBySymbolMasters; 16 | - (id)symbolsReferencedByInstances:(id)arg1; 17 | - (void)invalidateAffectedSymbolInstances; 18 | - (void)addSymbolMaster:(id)arg1; 19 | - (id)symbolWithID:(id)arg1; 20 | - (id)allSymbols; 21 | - (id)localSymbols; 22 | - (id)symbolsPageOrCreateIfNecessary; 23 | - (id)symbolsPage; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Headers/MSSymbolMaster.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import 8 | 9 | @interface MSSymbolMaster : NSObject 10 | 11 | @property(nonatomic) BOOL isDirty; // @synthesize isDirty=_isDirty; 12 | @property(nonatomic) long long changeIdentifier; // @synthesize changeIdentifier=_changeIdentifier; 13 | @property(readonly, nonatomic) NSSet *nestedSymbols; 14 | @property(readonly, nonatomic) NSArray *allInstances; 15 | @property(readonly, nonatomic) NSArray *allInfluencedInstances; 16 | @property(readonly, nonatomic) NSArray *availableOverrides; 17 | @property(readonly, nonatomic) NSString *name; 18 | 19 | - (id)parentSymbol; 20 | - (id)rootForNameUniquing; 21 | - (BOOL)hasInstances; 22 | - (id)nestedSymbolsSkipping:(id)arg1; 23 | - (id)newSymbolInstance; 24 | - (id)copyWithIDMapping:(id)arg1; 25 | - (void)invalidateModifiedSymbolCache; 26 | - (void)invalidateImmutableObject; 27 | - (void)syncPropertiesFromObject:(id)arg1; 28 | - (void)performInitWithImmutableModelObject:(id)arg1; 29 | - (id)unselectedPreviewTemplateImage; 30 | - (id)selectedPreviewTemplateImage; 31 | - (void)applyStyleToMenuItem:(id)arg1 withColorSpace:(id)arg2; 32 | - (BOOL)previewShouldIndicateSharedStyle; 33 | - (void)applyOverrides:(id)arg1 document:(id)arg2; 34 | 35 | @end 36 | 37 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/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 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2018 cyan-stivy.net. All rights reserved. 23 | 24 | 25 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNFetchResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNFetchResult.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CSNSymbolMasterItem; 12 | @class CSNNameTokenizer; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CSNFetchResult : NSObject 17 | @property (nonatomic, copy, readonly) NSArray *items; 18 | @property (nonatomic, assign, readonly) NSUInteger bottomLevel; 19 | 20 | - (instancetype)initWithItems:(NSArray *)items tokenizer:(CSNNameTokenizer *)tokenizer; 21 | 22 | - (NSArray *)tokens; 23 | - (NSArray *)tokensAtBottomLevel; 24 | - (NSArray *)tokensAtLevel:(NSInteger) level unique:(BOOL)unique; 25 | - (NSArray *)tokenStringUpToBottomLevel; 26 | - (NSArray *)tokenStringUpToBottomLevelUniquing:(BOOL)unique; 27 | - (NSArray *)tokenStringUpToLevel:(NSInteger)level unique:(BOOL)unique; 28 | 29 | - (BOOL)isTokenEndWithDelimeterAtBottomLevel; 30 | 31 | @end 32 | 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNFetchResult.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNFetchResult.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNFetchResult.h" 10 | #import "CSNSymbolMasterItem.h" 11 | #import "CSNNameTokenizer.h" 12 | 13 | @interface CSNFetchResult () 14 | 15 | @property (nonatomic, copy, readwrite) NSArray *items; 16 | @property (nonatomic, strong) CSNNameTokenizer *tokenizer; 17 | 18 | @end 19 | 20 | 21 | @implementation CSNFetchResult 22 | 23 | - (instancetype)initWithItems:(NSArray *)items tokenizer:(CSNNameTokenizer *)tokenizer 24 | { 25 | self = [super init]; 26 | if (self) { 27 | self.items = items; 28 | self.tokenizer = tokenizer; 29 | } 30 | return self; 31 | } 32 | 33 | - (NSString *)debugDescription 34 | { 35 | return [NSString stringWithFormat:@"<%@: %p, items: %@>", 36 | NSStringFromClass([self class]), 37 | self, 38 | self.items 39 | ]; 40 | } 41 | 42 | - (BOOL)isTokenEndWithDelimeterAtBottomLevel 43 | { 44 | return [self.tokenizer isEndWithDelimeterAtBottomLevel]; 45 | } 46 | 47 | - (NSUInteger)bottomLevel 48 | { 49 | if (self.tokenizer.count == 0) { 50 | return 0; 51 | } 52 | return self.tokenizer.count - 1; 53 | } 54 | 55 | - (NSArray *)tokens 56 | { 57 | NSMutableArray *tokens = [NSMutableArray array]; 58 | 59 | for (CSNSymbolMasterItem *item in self.items) { 60 | [tokens addObject:[item name]]; 61 | } 62 | 63 | return [tokens copy]; 64 | } 65 | 66 | - (NSArray *)tokensAtBottomLevel 67 | { 68 | return [self tokensAtLevel:self.bottomLevel unique:YES]; 69 | } 70 | 71 | - (NSArray *)tokensAtLevel:(NSInteger) level unique:(BOOL)unique 72 | { 73 | NSMutableArray *tokens = [NSMutableArray array]; 74 | 75 | for (CSNSymbolMasterItem *item in self.items) { 76 | NSString *token = [item tokenAtLevel:level]; 77 | if (unique) { 78 | if (![tokens containsObject:token]) { 79 | [tokens addObject:token]; 80 | } 81 | } else { 82 | [tokens addObject:token]; 83 | } 84 | } 85 | 86 | return [tokens copy]; 87 | } 88 | 89 | - (NSArray *)tokenStringUpToBottomLevel 90 | { 91 | return [self tokenStringUpToLevel:self.bottomLevel]; 92 | } 93 | 94 | - (NSArray *)tokenStringUpToBottomLevelUniquing:(BOOL)unique 95 | { 96 | return [self tokenStringUpToLevel:self.bottomLevel unique:unique]; 97 | } 98 | 99 | - (NSArray *)tokenStringUpToLevel:(NSInteger) level 100 | { 101 | return [self tokenStringUpToLevel:level unique:YES]; 102 | } 103 | 104 | - (NSArray *)tokenStringUpToLevel:(NSInteger)level unique:(BOOL)unique 105 | { 106 | NSMutableArray *tokens = [NSMutableArray array]; 107 | 108 | for (CSNSymbolMasterItem *item in self.items) { 109 | NSString *string = [item tokenStringUpToLevel:level]; 110 | if (unique) { 111 | if (![tokens containsObject:string]) { 112 | [tokens addObject:string]; 113 | } 114 | } else { 115 | [tokens addObject:string]; 116 | } 117 | 118 | } 119 | 120 | NSStringCompareOptions compareOptions = (NSNumericSearch | NSCaseInsensitiveSearch); 121 | [tokens sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { 122 | return [obj1 compare:obj2 options:compareOptions]; 123 | }]; 124 | 125 | return [tokens copy]; 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNNameTokenizer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNNameTokenizer.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CSNNameTokenizer : NSObject 14 | 15 | @property (nonatomic, assign) NSUInteger count; 16 | 17 | + (NSInteger)levelWithString:(NSString *)name; 18 | 19 | - (instancetype)initWithString:(NSString *)name; 20 | 21 | - (NSInteger)levelWithString:(NSString *)name; 22 | 23 | - (NSInteger)bottomLevel; 24 | 25 | - (NSString *)tokenStringUpToLevel:(NSInteger)level; 26 | 27 | - (NSArray *)tokensUpToLevel:(NSInteger)level; 28 | 29 | - (NSString *)tokenAtLevel:(NSInteger)level; 30 | 31 | - (BOOL)isEndWithDelimeterAtLevel:(NSInteger)level; 32 | 33 | - (BOOL)isEndWithDelimeterAtBottomLevel; 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNNameTokenizer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNNameTokenizer.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNNameTokenizer.h" 10 | 11 | @interface CSNNameTokenizer () 12 | @property (nonatomic, copy) NSString *name; 13 | @property (nonatomic, copy) NSArray *tokens; 14 | @end 15 | 16 | @implementation CSNNameTokenizer 17 | 18 | + (NSInteger)levelWithString:(NSString *)name 19 | { 20 | NSUInteger count = [[self tokenize:name] count]; 21 | if (count == 0) { 22 | return NSNotFound; 23 | } 24 | return count - 1; 25 | } 26 | 27 | - (instancetype)initWithString:(NSString *) name 28 | { 29 | self = [super init]; 30 | if (self) { 31 | self.name = name; 32 | self.tokens = [[self class] tokenize:_name]; 33 | } 34 | return self; 35 | } 36 | 37 | - (NSUInteger)count 38 | { 39 | return self.tokens.count; 40 | } 41 | 42 | - (NSInteger)levelWithString:(NSString *)name 43 | { 44 | for (NSInteger i = 0; i < self.tokens.count; i++) { 45 | NSString *token = self.tokens[i]; 46 | if ([token isEqualToString:name]) { 47 | return i; 48 | } 49 | } 50 | 51 | return NSNotFound; 52 | } 53 | 54 | - (NSInteger)bottomLevel 55 | { 56 | if (self.count == 0) { 57 | return NSNotFound; 58 | } 59 | return self.count - 1; 60 | } 61 | 62 | - (NSString *)tokenStringUpToLevel:(NSInteger)level 63 | { 64 | return [[self tokensUpToLevel:level] componentsJoinedByString:@""]; 65 | } 66 | 67 | - (NSArray *)tokensUpToLevel:(NSInteger)level 68 | { 69 | if (self.tokens.count <= level) { 70 | return nil; 71 | } 72 | 73 | NSMutableArray *tokens = [NSMutableArray array]; 74 | NSInteger upto = MIN((NSInteger)self.tokens.count - 1, level) + 1; 75 | for (NSInteger i = 0; i < upto; i++) { 76 | [tokens addObject:self.tokens[i]]; 77 | } 78 | 79 | return [tokens copy]; 80 | } 81 | 82 | - (NSString *)tokenAtLevel:(NSInteger) level 83 | { 84 | if (self.tokens.count <= level) { 85 | return nil; 86 | } 87 | 88 | return self.tokens[level]; 89 | } 90 | 91 | - (BOOL)isEndWithDelimeterAtLevel:(NSInteger)level 92 | { 93 | NSString *token = [self tokenAtLevel:level]; 94 | if (token == nil) { 95 | return NO; 96 | } 97 | 98 | if ([token hasSuffix:@"/"]) { 99 | return YES; 100 | } 101 | 102 | if ([token hasSuffix:@"/ "]) { 103 | return YES; 104 | } 105 | 106 | return NO; 107 | } 108 | 109 | - (BOOL)isEndWithDelimeterAtBottomLevel 110 | { 111 | return [self isEndWithDelimeterAtLevel:[self bottomLevel]]; 112 | } 113 | 114 | - (NSString *)description 115 | { 116 | return [NSString stringWithFormat:@"<%@: %p, tokens: %@>", 117 | NSStringFromClass([self class]), 118 | self, 119 | self.tokens 120 | ]; 121 | } 122 | 123 | #pragma mark - Private 124 | 125 | + (NSArray *)tokenize: (NSString *)string 126 | { 127 | NSMutableArray *tokens = [NSMutableArray array]; 128 | NSMutableCharacterSet *characterSet = [NSMutableCharacterSet alphanumericCharacterSet]; 129 | [characterSet removeCharactersInString:@"/"]; 130 | NSScanner *scanner = [NSScanner scannerWithString:string]; 131 | NSString *name = nil; 132 | NSString *delimiter = nil; 133 | while (![scanner isAtEnd]) { 134 | [scanner scanUpToString:@"/" intoString:&name]; 135 | // NSLog(@"`%@`", name); 136 | if ([scanner scanUpToCharactersFromSet:characterSet intoString:&delimiter]) { 137 | // NSLog(@"`%@`", delimiter); 138 | [tokens addObject:[name stringByAppendingString:delimiter]]; 139 | } else { 140 | [tokens addObject:name]; 141 | } 142 | } 143 | return [tokens copy]; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNSymbolMasterItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSymbolMasterItem.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CSNSymbolMasterItem : NSObject 14 | 15 | @property (nonatomic, copy) NSString *name; 16 | 17 | @property (nonatomic, assign) NSUInteger tokenCount; 18 | 19 | - (instancetype)initWithName:(NSString *)symbolName; 20 | 21 | - (NSString *)tokenStringUpToLevel:(NSInteger)level; 22 | 23 | - (NSArray *)tokensUpToLevel:(NSInteger)level; 24 | 25 | - (NSString *)tokenAtLevel:(NSInteger)level; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNSymbolMasterItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSymbolMasterItem.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNSymbolMasterItem.h" 10 | #import "CSNNameTokenizer.h" 11 | 12 | @interface CSNSymbolMasterItem ( ) 13 | @property (nonatomic, strong) CSNNameTokenizer *tokenizer; 14 | @end 15 | 16 | @implementation CSNSymbolMasterItem 17 | 18 | - (instancetype)initWithName:(NSString *)symbolName 19 | { 20 | self = [super init]; 21 | if (self) { 22 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [symbolName debugDescription]); 23 | self.tokenizer = [[CSNNameTokenizer alloc] initWithString:symbolName]; 24 | } 25 | return self; 26 | } 27 | 28 | - (NSUInteger)count 29 | { 30 | return self.tokenizer.count; 31 | } 32 | 33 | - (NSString *)tokenStringUpToLevel:(NSInteger)level 34 | { 35 | return [self.tokenizer tokenStringUpToLevel:level]; 36 | } 37 | 38 | - (NSArray *)tokensUpToLevel:(NSInteger)level 39 | { 40 | return [self.tokenizer tokensUpToLevel:level]; 41 | } 42 | 43 | - (NSString *)tokenAtLevel:(NSInteger)level 44 | { 45 | return [self.tokenizer tokenAtLevel:level]; 46 | } 47 | 48 | - (NSString *)description 49 | { 50 | return [NSString stringWithFormat:@"<%@: %p, %@>", 51 | NSStringFromClass([self class]), 52 | self, 53 | self.tokenizer 54 | ]; 55 | } 56 | @end 57 | 58 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNSymbolRepository.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSymbolRepository.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CSNFetchResult, CSNSymbolMasterItem; 12 | @class MSDocumentData; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface CSNSymbolRepository : NSObject 17 | 18 | - (instancetype)initWithDocumentData:(MSDocumentData *)docData; 19 | - (instancetype)initWithNames:(NSArray *)names; 20 | 21 | - (CSNFetchResult *)fetchItemsByString:(NSString *)searchword; 22 | - (CSNFetchResult *)listUpItemsUsingString:(NSString *)word; 23 | - (NSArray *)fetchItemsByString:(NSString *)searchword atLevel:(NSUInteger)level; 24 | 25 | @end 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Models/CSNSymbolRepository.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSymbolRepository.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNSymbolRepository.h" 10 | #import "CSNSymbolMasterItem.h" 11 | #import "CSNNameTokenizer.h" 12 | #import "CSNFetchResult.h" 13 | #import "MSDocumentData.h" 14 | #import "MSSymbolMaster.h" 15 | 16 | @interface CSNSymbolRepository () 17 | 18 | @property (nonatomic, copy) NSArray *items; 19 | 20 | @end 21 | 22 | 23 | @implementation CSNSymbolRepository 24 | 25 | - (instancetype)initWithDocumentData:(MSDocumentData *)docData 26 | { 27 | // NSLog(@"👺 %s %@", __PRETTY_FUNCTION__, [docData.localSymbols debugDescription]); 28 | NSMutableArray *temp = [NSMutableArray array]; 29 | for (MSSymbolMaster *master in docData.localSymbols) { 30 | [temp addObject:master.name]; 31 | } 32 | return [self initWithNames:temp]; 33 | } 34 | 35 | - (instancetype)initWithNames:(NSArray *)names 36 | { 37 | self = [super init]; 38 | if (self) { 39 | NSMutableArray *temp = [NSMutableArray array]; 40 | for (NSString *name in names) { 41 | CSNSymbolMasterItem *item = [[CSNSymbolMasterItem alloc] initWithName:name]; 42 | [temp addObject:item]; 43 | } 44 | 45 | self.items = [temp copy]; 46 | } 47 | return self; 48 | } 49 | 50 | - (CSNFetchResult *)fetchItemsByString:(NSString *)searchword 51 | { 52 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:searchword]; 53 | NSInteger level = [tokenizer bottomLevel]; 54 | if (level == NSNotFound) { 55 | NSLog(@"👺 %s level NSNotFound for '%@'", __PRETTY_FUNCTION__, [NSNumber numberWithInteger:level]); 56 | return nil; 57 | } 58 | 59 | NSMutableArray *targetItems = [self.items copy]; 60 | NSMutableArray *filterdItems = [NSMutableArray array]; 61 | 62 | for (NSInteger i = 0; i < tokenizer.count; i++) { 63 | [filterdItems removeAllObjects]; 64 | BOOL isLastLevel = (i == tokenizer.count - 1); 65 | if (isLastLevel) { 66 | for (CSNSymbolMasterItem *item in targetItems) { 67 | NSString *name = [item tokenAtLevel:i]; 68 | NSString *searchWordAtLevel = [tokenizer tokenAtLevel:i]; 69 | if ([[name lowercaseString] hasPrefix:[searchWordAtLevel lowercaseString]]) { 70 | [filterdItems addObject:item]; 71 | } 72 | } 73 | } else { 74 | for (CSNSymbolMasterItem *item in targetItems) { 75 | NSString *name = [item tokenAtLevel:i]; 76 | NSString *searchWordAtLevel = [tokenizer tokenAtLevel:i]; 77 | if ([name isEqualToString:searchWordAtLevel]) { 78 | [filterdItems addObject:item]; 79 | } 80 | } 81 | } 82 | 83 | targetItems = [filterdItems mutableCopy]; 84 | } 85 | 86 | if ([filterdItems count] == 0) { 87 | return nil; 88 | } 89 | 90 | return [[CSNFetchResult alloc] initWithItems:[filterdItems copy] tokenizer:tokenizer]; 91 | } 92 | 93 | - (CSNFetchResult *)listUpItemsUsingString:(NSString *)word 94 | { 95 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:word]; 96 | NSMutableArray *targetItems = [self.items copy]; 97 | NSMutableArray *filterdItems = [NSMutableArray array]; 98 | 99 | if (tokenizer.count == 0) { 100 | return [[CSNFetchResult alloc] initWithItems:targetItems tokenizer:tokenizer]; 101 | } 102 | 103 | for (NSInteger i = 0; i < tokenizer.count; i++) { 104 | [filterdItems removeAllObjects]; 105 | BOOL isLastLevel = (i == tokenizer.count - 1); 106 | if (isLastLevel) { 107 | for (CSNSymbolMasterItem *item in targetItems) { 108 | NSString *name = [item tokenAtLevel:i]; 109 | NSString *searchWordAtLevel = [tokenizer tokenAtLevel:i]; 110 | if ([searchWordAtLevel length] == 0) { 111 | [filterdItems addObject:item]; 112 | } else if ([[name lowercaseString] hasPrefix:[searchWordAtLevel lowercaseString]]) { 113 | [filterdItems addObject:item]; 114 | } 115 | } 116 | } else { 117 | for (CSNSymbolMasterItem *item in targetItems) { 118 | NSString *name = [item tokenAtLevel:i]; 119 | NSString *searchWordAtLevel = [tokenizer tokenAtLevel:i]; 120 | if ([name isEqualToString:searchWordAtLevel]) { 121 | [filterdItems addObject:item]; 122 | } 123 | } 124 | } 125 | 126 | targetItems = [filterdItems mutableCopy]; 127 | } 128 | 129 | if ([tokenizer isEndWithDelimeterAtBottomLevel]) { 130 | for (CSNSymbolMasterItem *item in targetItems) { 131 | NSString *name = [item tokenAtLevel:[tokenizer bottomLevel] + 1]; 132 | NSString *searchWordAtLevel = [tokenizer tokenAtLevel:[tokenizer bottomLevel] + 1]; 133 | if ([name isEqualToString:searchWordAtLevel]) { 134 | [filterdItems addObject:item]; 135 | } 136 | } 137 | } 138 | 139 | if ([filterdItems count] == 0) { 140 | return nil; 141 | } 142 | 143 | return [[CSNFetchResult alloc] initWithItems:[filterdItems copy] tokenizer:tokenizer]; 144 | } 145 | 146 | - (NSArray *)fetchItemsByString:(NSString *)searchword atLevel:(NSUInteger)level 147 | { 148 | return [self fetchItemsByString:searchword atLevel:level fazzy:YES]; 149 | } 150 | 151 | 152 | #pragma mark - Private 153 | 154 | - (NSArray *)fetchItemsByString:(NSString *)searchword atLevel:(NSUInteger)level fazzy:(BOOL)isFazzy 155 | { 156 | NSArray *nameAtLevel = [self namesAtLevel:level unique:NO]; 157 | 158 | NSPredicate *predicate = nil; 159 | if (isFazzy) { 160 | predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", searchword]; 161 | } else { 162 | predicate = [NSPredicate predicateWithFormat:@"SELF == %@", searchword]; 163 | } 164 | 165 | return [nameAtLevel filteredArrayUsingPredicate:predicate]; 166 | } 167 | 168 | - (NSArray *)namesAtLevel:(NSUInteger)level unique:(BOOL)unique 169 | { 170 | NSMutableArray *namesAtLevel = [NSMutableArray array]; 171 | 172 | for (CSNSymbolMasterItem *item in self.items) { 173 | NSString *name = [item tokenAtLevel:level]; 174 | if (name != nil) { 175 | if (unique) { 176 | if ([namesAtLevel containsObject:name] == NO) { 177 | [namesAtLevel addObject:name]; 178 | } 179 | } else { 180 | [namesAtLevel addObject:name]; 181 | } 182 | } 183 | } 184 | 185 | return [namesAtLevel copy]; 186 | } 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/SymbolNameAutocomplete.h: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolNameAutocomplete.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SymbolNameAutocomplete. 12 | FOUNDATION_EXPORT double SymbolNameAutocompleteVersionNumber; 13 | 14 | //! Project version string for SymbolNameAutocomplete. 15 | FOUNDATION_EXPORT const unsigned char SymbolNameAutocompleteVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/SymbolNameAutocompletePluginController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolNameAutocompletePluginController.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class MSCreateSymbolNamingSheet, MSDocumentData; 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface SymbolNameAutocompletePluginController : NSObject 16 | 17 | @property (nonatomic, assign, getter=isEnabled) BOOL enabled; 18 | @property (nonatomic, weak) MSCreateSymbolNamingSheet *namingSheet; 19 | @property (nonatomic, weak) MSDocumentData *documentData; 20 | 21 | + (instancetype)sharedController; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/SymbolNameAutocompletePluginController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolNameAutocompletePluginController.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/22. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "SymbolNameAutocompletePluginController.h" 10 | #import "CSNSuggestionController.h" 11 | #import "CSNSymbolRepository.h" 12 | #import "MSCreateSymbolNamingSheet.h" 13 | #import "MSDocumentData.h" 14 | 15 | @interface SymbolNameAutocompletePluginController () 16 | 17 | @property (nonatomic, strong) CSNSuggestionController *suggestionController; 18 | 19 | @end 20 | 21 | @implementation SymbolNameAutocompletePluginController 22 | 23 | #pragma mark - Singleton 24 | 25 | + (instancetype)sharedController 26 | { 27 | static dispatch_once_t once; 28 | static id _sharedInstance = nil; 29 | dispatch_once(&once, ^{ 30 | _sharedInstance = [[self alloc] init]; 31 | }); 32 | 33 | return _sharedInstance; 34 | } 35 | 36 | #pragma mark - Properties 37 | 38 | - (void)setEnabled:(BOOL)enabled 39 | { 40 | if (_enabled == enabled) { 41 | return; 42 | } 43 | 44 | _enabled = enabled; 45 | 46 | if (enabled) { 47 | self.suggestionController = [[CSNSuggestionController alloc] init]; 48 | } else { 49 | self.suggestionController = nil; 50 | } 51 | } 52 | 53 | - (void)setNamingSheet:(MSCreateSymbolNamingSheet *)sheet 54 | { 55 | if (_namingSheet == sheet) { 56 | return ; 57 | } 58 | 59 | _namingSheet = sheet; 60 | 61 | // NSLog(@"%s %@", __PRETTY_FUNCTION__, @"setNamingSheet is Called 👺"); 62 | 63 | _namingSheet.symbolNameField.delegate = self.suggestionController; 64 | self.suggestionController.textFieldProxyDelegate = (id)_namingSheet; 65 | self.suggestionController.window = _namingSheet.window; 66 | } 67 | 68 | - (void)setDocumentData:(MSDocumentData *)docData 69 | { 70 | _documentData = docData; 71 | 72 | // NSLog(@"%s %@", __PRETTY_FUNCTION__, @"setDocumentData is Called 👺"); 73 | 74 | if (_documentData != nil) { 75 | self.suggestionController.symbolRepository = [[CSNSymbolRepository alloc] initWithDocumentData:_documentData]; 76 | } 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Views/CSNRowView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNRowView.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CSNRowView : NSTableRowView 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Views/CSNRowView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNRowView.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNRowView.h" 10 | #import "NSColor+Additions.h" 11 | 12 | @implementation CSNRowView 13 | 14 | - (NSBackgroundStyle)interiorBackgroundStyle 15 | { 16 | return self.isSelected ? NSBackgroundStyleEmphasized : NSBackgroundStyleNormal; 17 | } 18 | 19 | - (void)drawSelectionInRect:(NSRect)dirtyRect 20 | { 21 | [[NSColor csn_selectionColor] setFill]; 22 | 23 | [[NSBezierPath bezierPathWithRect:self.bounds] fill]; 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Views/CSNSuggestionCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionCell.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CSNSuggestionCell : NSTableCellView 14 | 15 | @property (nonatomic, copy) NSString *suggestion; 16 | 17 | + (CGFloat)height; 18 | + (NSString *)reuseIdentifier; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Views/CSNSuggestionCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionCell.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNSuggestionCell.h" 10 | #import "NSColor+Additions.h" 11 | 12 | static const CGFloat CSNSuggestionCellHeight = 32.0f; 13 | static const CGFloat CSNSuggestionCellMargin = 8.0f; 14 | 15 | @interface CSNSuggestionCell () 16 | @property (nonatomic, strong) NSTextField *suggeestionTextField; 17 | @end 18 | 19 | 20 | @implementation CSNSuggestionCell 21 | 22 | + (CGFloat)height 23 | { 24 | return CSNSuggestionCellHeight; 25 | } 26 | 27 | + (NSString *)reuseIdentifier 28 | { 29 | return NSStringFromClass([self class]); 30 | } 31 | 32 | #pragma mark - Initializers 33 | 34 | - (instancetype)initWithFrame:(NSRect)frame 35 | { 36 | self = [super initWithFrame:frame]; 37 | 38 | if (!self) { 39 | return nil; 40 | } 41 | 42 | self.identifier = [[self class] reuseIdentifier]; 43 | 44 | self.suggeestionTextField = [[NSTextField alloc] init]; 45 | self.suggeestionTextField.bordered = NO; 46 | self.suggeestionTextField.drawsBackground = NO; 47 | self.suggeestionTextField.editable = NO; 48 | self.suggeestionTextField.selectable = NO; 49 | self.suggeestionTextField.usesSingleLineMode = YES; 50 | self.suggeestionTextField.lineBreakMode = NSLineBreakByTruncatingMiddle; 51 | self.suggeestionTextField.alignment = NSTextAlignmentLeft; 52 | self.suggeestionTextField.font = [NSFont systemFontOfSize:14.0]; 53 | 54 | NSColor *textFieldTextColor = [NSColor csn_textColor]; 55 | if (textFieldTextColor) { 56 | self.suggeestionTextField.textColor = textFieldTextColor; 57 | } 58 | 59 | [self addSubview:self.suggeestionTextField]; 60 | 61 | self.translatesAutoresizingMaskIntoConstraints = NO; 62 | self.suggeestionTextField.translatesAutoresizingMaskIntoConstraints = NO; 63 | 64 | NSArray *constrains = @[ 65 | [self.suggeestionTextField.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:CSNSuggestionCellMargin], 66 | [self.suggeestionTextField.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant: -CSNSuggestionCellMargin], 67 | [self.suggeestionTextField.centerYAnchor constraintEqualToAnchor:self.centerYAnchor] 68 | ]; 69 | 70 | [NSLayoutConstraint activateConstraints:constrains]; 71 | 72 | return self; 73 | } 74 | 75 | #pragma mark - Properties 76 | 77 | - (void)setSuggestion:(NSString *)suggestion 78 | { 79 | _suggestion = [suggestion copy]; 80 | self.suggeestionTextField.stringValue = _suggestion; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Views/CSNSuggestionsTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionsTableView.h 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol CSNSuggestionsTableViewDelegate; 14 | 15 | @interface CSNSuggestionsTableView : NSTableView 16 | 17 | @end 18 | 19 | @protocol CSNSuggestionsTableViewDelegate 20 | @optional 21 | 22 | - (void)tableView:(NSTableView *)tableView didClickRow:(NSInteger)row; 23 | - (void)selectRowAtIndex:(NSInteger)index; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/Views/CSNSuggestionsTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSuggestionsTableView.m 3 | // SymbolNameAutocomplete 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.net. All rights reserved. 7 | // 8 | 9 | #import "CSNSuggestionsTableView.h" 10 | 11 | @interface CSNSuggestionsTableView ( ) 12 | @property (nonatomic, strong) NSTrackingArea *trackingArea; 13 | @end 14 | 15 | 16 | @implementation CSNSuggestionsTableView 17 | 18 | #pragma mark - NSTableView 19 | 20 | - (void)reloadData 21 | { 22 | [super reloadData]; 23 | 24 | if (!self.window) { 25 | return; 26 | } 27 | 28 | [self reloadSelectionWithMouseLocationInWindow:self.window.mouseLocationOutsideOfEventStream]; 29 | } 30 | 31 | #pragma mark - NSResponder 32 | 33 | - (void)updateTrackingAreas 34 | { 35 | if (self.trackingArea != nil) { 36 | [self removeTrackingArea:self.trackingArea]; 37 | } 38 | 39 | self.trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseMoved | NSTrackingActiveInActiveApp owner:self userInfo:nil]; 40 | [self addTrackingArea:self.trackingArea]; 41 | 42 | [super updateTrackingAreas]; 43 | } 44 | 45 | - (void)mouseDown:(NSEvent *)event 46 | { 47 | NSPoint convertedLocation = [self convertPoint:event.locationInWindow toView:nil]; 48 | NSInteger row = [self rowAtPoint:convertedLocation]; 49 | 50 | id delegate = (id )self.delegate; 51 | if (row >= 0 && [delegate respondsToSelector:@selector(tableView:didClickRow:)]) { 52 | [delegate tableView:self didClickRow:row]; 53 | } 54 | } 55 | 56 | - (void)mouseMoved:(NSEvent *)event 57 | { 58 | [self reloadSelectionWithMouseLocationInWindow:event.locationInWindow]; 59 | } 60 | 61 | #pragma mark - Private 62 | 63 | - (void)reloadSelectionWithMouseLocationInWindow:(NSPoint)mouseLocationInWindow 64 | { 65 | NSPoint convertedLocation = [self convertPoint:mouseLocationInWindow toView:nil]; 66 | NSInteger row = [self rowAtPoint:convertedLocation]; 67 | 68 | if (row < 0 || self.selectedRow == row) { 69 | return; 70 | } 71 | 72 | BOOL shouldSelect = [self.delegate tableView:self shouldSelectRow:row] ?: YES; 73 | 74 | if (shouldSelect) { 75 | [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; 76 | id delegate = (id )self.delegate; 77 | if ([delegate respondsToSelector:@selector(selectRowAtIndex:)]) { 78 | [delegate selectRowAtIndex:row]; 79 | } 80 | } 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/_Headers/CHSheetController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import "CHWindowController.h" 8 | 9 | #import 10 | #import 11 | 12 | @class NSCountedSet, NSString, NSWindow; 13 | 14 | @interface CHSheetController : CHWindowController 15 | { 16 | id _object; 17 | NSWindow *_parentWindow; 18 | NSCountedSet *_selfReferences; 19 | } 20 | 21 | + (id)findSuitableWindowForSheet; 22 | + (id)runForWindow:(id)arg1 withObject:(id)arg2; 23 | + (id)runForWindow:(id)arg1; 24 | @property(retain, nonatomic) NSCountedSet *selfReferences; // @synthesize selfReferences=_selfReferences; 25 | @property(nonatomic) __weak NSWindow *parentWindow; // @synthesize parentWindow=_parentWindow; 26 | @property(retain, nonatomic) id object; // @synthesize object=_object; 27 | 28 | - (void)sheetWillClose; 29 | - (id)_init; 30 | - (id)touchBar:(id)arg1 makeItemForIdentifier:(id)arg2; 31 | - (id)makeTouchBar; 32 | - (SEL)selectorForTouchbarItemIdentifier:(id)arg1; 33 | - (id)touchBarItemIdentifiers; 34 | - (id)windowNibName; 35 | - (void)closeSheet; 36 | - (void)cancel:(id)arg1; 37 | - (void)confirm:(id)arg1; 38 | - (id)run; 39 | - (void)releaseSelf; 40 | - (void)retainSelf; 41 | 42 | // Remaining properties 43 | @property(readonly, copy) NSString *debugDescription; 44 | @property(readonly, copy) NSString *description; 45 | @property(readonly) unsigned long long hash; 46 | @property(readonly) Class superclass; 47 | 48 | @end 49 | 50 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/_Headers/CHWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import 8 | 9 | @interface CHWindowController : NSWindowController 10 | { 11 | } 12 | 13 | - (void)dealloc; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/_Headers/MSCreateSymbolNamingSheet.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import "CHSheetController.h" 8 | 9 | @class NSButton, NSTextField; 10 | 11 | @interface MSCreateSymbolNamingSheet : CHSheetController 12 | { 13 | NSButton *_moveSymbolToPageCheckbox; 14 | NSButton *_confirmButton; 15 | NSTextField *_symbolNameField; 16 | NSTextField *_symbolPageField; 17 | } 18 | 19 | 20 | @property(retain, nonatomic) NSTextField *symbolPageField; // @synthesize symbolPageField=_symbolPageField; 21 | @property(retain, nonatomic) NSTextField *symbolNameField; // @synthesize symbolNameField=_symbolNameField; 22 | @property(retain, nonatomic) NSButton *confirmButton; // @synthesize confirmButton=_confirmButton; 23 | @property(retain, nonatomic) NSButton *moveSymbolToPageCheckbox; // @synthesize moveSymbolToPageCheckbox=_moveSymbolToPageCheckbox; 24 | 25 | - (void)validateConfirmButton; 26 | - (void)controlTextDidChange:(id)arg1; 27 | - (void)setShouldShowMoveCheckbox:(BOOL)arg1; 28 | - (void)setSuggestedName:(id)arg1; 29 | - (void)setSymbolPageName:(id)arg1; 30 | - (void)confirm:(id)arg1; 31 | - (void)awakeFromNib; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/_Headers/MSDocumentData.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import "_MSDocumentData.h" 8 | 9 | #import "MSDocumentData-Protocol.h" 10 | #import "MSLayerContainment-Protocol.h" 11 | 12 | @class BCCache, MSFontList, MSPage, NSArray, NSDictionary; 13 | @protocol MSDocumentDataDelegate; 14 | 15 | @interface MSDocumentData : _MSDocumentData 16 | { 17 | BOOL _autoExpandGroupsInLayerList; 18 | NSDictionary *_symbolMap; 19 | NSArray *_selectedOverrides; 20 | BCCache *_cache; 21 | id _delegate; 22 | NSDictionary *_metadata; 23 | MSFontList *_fontList; 24 | } 25 | 26 | + (void)initialize; 27 | @property(retain, nonatomic) MSFontList *fontList; // @synthesize fontList=_fontList; 28 | @property(retain, nonatomic) NSDictionary *metadata; // @synthesize metadata=_metadata; 29 | @property(nonatomic) BOOL autoExpandGroupsInLayerList; // @synthesize autoExpandGroupsInLayerList=_autoExpandGroupsInLayerList; 30 | @property(nonatomic) __weak id delegate; // @synthesize delegate=_delegate; 31 | @property(retain, nonatomic) BCCache *cache; // @synthesize cache=_cache; 32 | - (void).cxx_destruct; 33 | - (void)determineCurrentArtboard; 34 | - (void)refreshOverlay; 35 | - (void)refreshOverlayInRect:(struct CGRect)arg1; 36 | - (void)immediatelyShowSelectionForAllLayers; 37 | - (void)temporarilyHideSelectionForLayers:(id)arg1; 38 | - (void)replaceExistingCreationMetadata; 39 | - (void)removeShareableObjectsFromInstanceOverrides:(id)arg1; 40 | - (id)images; 41 | - (id)layerStyleWithID:(id)arg1; 42 | - (id)textStyleWithID:(id)arg1; 43 | - (id)allLayerStyles; 44 | - (id)allTextStyles; 45 | - (id)sharedObjectContainerOfType:(unsigned long long)arg1; 46 | @property(retain, nonatomic) NSArray *selectedOverrides; // @synthesize selectedOverrides=_selectedOverrides; 47 | - (void)purgeForeignObjects; 48 | - (void)purgeForeignStyles; 49 | - (id)stylesReferencedInDocument; 50 | - (void)purgeForeignSymbols; 51 | - (id)symbolsReferencedBySymbolInstances; 52 | - (id)symbolsReferencedBySymbolMasters; 53 | - (id)symbolsReferencedByInstances:(id)arg1; 54 | - (void)enumerateForeignObjects:(id)arg1 withLibraries:(id)arg2 block:(CDUnknownBlockType)arg3; 55 | - (id)libraryForForeignObject:(id)arg1 inLibraries:(id)arg2; 56 | - (void)invalidateAffectedSymbolInstances; 57 | - (id)addCopyOfInstanceMasterToDocumentIfNecessary:(id)arg1; 58 | - (void)addSymbolMaster:(id)arg1; 59 | - (id)addCopyOfMasterToDocumentIfNecessary:(id)arg1; 60 | - (id)symbolWithID:(id)arg1; 61 | @property(readonly, nonatomic) NSDictionary *symbolMap; // @synthesize symbolMap=_symbolMap; 62 | - (id)allForeignObjects; 63 | - (id)allSymbols; 64 | - (id)localSymbols; 65 | - (id)allArtboards; 66 | - (void)populateDictionary:(id)arg1 withChildrenOf:(id)arg2; 67 | - (id)layersByObjectID; 68 | - (id)artboardWithID:(id)arg1; 69 | - (id)layerWithID:(id)arg1; 70 | - (void)layerTreeLayoutDidChange; 71 | - (id)selectedLayers; 72 | - (BOOL)documentIsEmpty; 73 | - (id)nameForNewPage; 74 | - (id)symbolsPageOrCreateIfNecessary; 75 | - (id)symbolsPage; 76 | - (id)addBlankPage; 77 | - (void)removePages:(id)arg1 detachInstances:(BOOL)arg2; 78 | @property(retain, nonatomic) MSPage *currentPage; 79 | - (void)setCurrentPageIndex:(unsigned long long)arg1; 80 | - (void)dealloc; 81 | - (id)documentData; 82 | - (void)copyPropertiesToObject:(id)arg1 options:(unsigned long long)arg2; 83 | - (void)objectDidInit; 84 | - (void)performInitEmptyObject; 85 | - (void)performInitWithImmutableModelObject:(id)arg1; 86 | - (id)defaultPagesArray; 87 | - (void)object:(id)arg1 didChangeProperty:(id)arg2; 88 | - (void)convertToColorSpace:(unsigned long long)arg1; 89 | - (void)assignColorSpace:(unsigned long long)arg1; 90 | - (void)replaceInstancesOfColor:(id)arg1 withColor:(id)arg2 ignoreAlphaWhenMatching:(BOOL)arg3 replaceAlphaOfOriginalColor:(BOOL)arg4; 91 | - (void)enumerateColorConvertiblesIgnoringForeignSymbols:(CDUnknownBlockType)arg1; 92 | - (void)replaceFonts:(id)arg1; 93 | - (void)invalidateFonts; 94 | - (BOOL)enumerateLayersWithOptions:(unsigned long long)arg1 block:(CDUnknownBlockType)arg2; 95 | - (void)enumerateLayers:(CDUnknownBlockType)arg1; 96 | - (id)lastLayer; 97 | - (id)firstLayer; 98 | - (unsigned long long)indexOfLayer:(id)arg1; 99 | - (id)layerAtIndex:(unsigned long long)arg1; 100 | - (BOOL)containsNoOrOneLayers; 101 | - (BOOL)containsLayers; 102 | - (BOOL)containsMultipleLayers; 103 | - (BOOL)containsOneLayer; 104 | - (unsigned long long)containedLayersCount; 105 | - (id)containedLayers; 106 | - (id)metadataForKey:(id)arg1 object:(id)arg2; 107 | - (void)storeMetadata:(id)arg1 forKey:(id)arg2 object:(id)arg3; 108 | - (id)UIMetadataKey; 109 | 110 | // Remaining properties 111 | @property(readonly, nonatomic) NSArray *pages; 112 | 113 | @end 114 | 115 | -------------------------------------------------------------------------------- /SymbolNameAutocomplete/_Headers/NSToolbarDelegate-Protocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by class-dump 3.5 (64 bit) (Debug version compiled Jul 6 2018 12:02:43). 3 | // 4 | // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. 5 | // 6 | 7 | #import 8 | 9 | @class NSArray, NSNotification, NSString, NSToolbar, NSToolbarItem; 10 | 11 | @protocol NSToolbarDelegate 12 | 13 | @optional 14 | - (void)toolbarDidRemoveItem:(NSNotification *)arg1; 15 | - (void)toolbarWillAddItem:(NSNotification *)arg1; 16 | - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)arg1; 17 | - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)arg1; 18 | - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)arg1; 19 | - (NSToolbarItem *)toolbar:(NSToolbar *)arg1 itemForItemIdentifier:(NSString *)arg2 willBeInsertedIntoToolbar:(BOOL)arg3; 20 | @end 21 | 22 | -------------------------------------------------------------------------------- /SymbolNameAutocompleteTests/CSNNameTokenizerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNNameTokenizerTests.m 3 | // SymbolNameAutocompleteTests 4 | // 5 | // Created by griffin-stewie on 2018/11/25. 6 | // Copyright © 2018 cyan-stivy.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CSNNameTokenizer.h" 11 | 12 | @interface CSNNameTokenizerTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation CSNNameTokenizerTests 17 | 18 | - (void)setUp 19 | { 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | } 27 | 28 | - (void)testSymbolNameSeparatedWithSpace 29 | { 30 | { 31 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem / Online"]; 32 | XCTAssertEqual(tokenizer.count, 2); 33 | XCTAssertFalse([tokenizer isEndWithDelimeterAtBottomLevel]); 34 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 35 | XCTAssertEqualObjects(firstToken, @"ListItem / "); 36 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 37 | XCTAssertEqualObjects(secondToken, @"Online"); 38 | } 39 | 40 | { 41 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem / Online / button"]; 42 | XCTAssertEqual(tokenizer.count, 3); 43 | XCTAssertFalse([tokenizer isEndWithDelimeterAtBottomLevel]); 44 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 45 | XCTAssertEqualObjects(firstToken, @"ListItem / "); 46 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 47 | XCTAssertEqualObjects(secondToken, @"Online / "); 48 | NSString *thirdToken = [tokenizer tokenAtLevel: 2]; 49 | XCTAssertEqualObjects(thirdToken, @"button"); 50 | } 51 | 52 | } 53 | 54 | - (void)testSymbolNameSeparatedWithoutSpace 55 | { 56 | { 57 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem/Online"]; 58 | XCTAssertEqual(tokenizer.count, 2); 59 | XCTAssertFalse([tokenizer isEndWithDelimeterAtBottomLevel]); 60 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 61 | XCTAssertEqualObjects(firstToken, @"ListItem/"); 62 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 63 | XCTAssertEqualObjects(secondToken, @"Online"); 64 | } 65 | 66 | { 67 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem/Online/button"]; 68 | XCTAssertEqual(tokenizer.count, 3); 69 | XCTAssertFalse([tokenizer isEndWithDelimeterAtBottomLevel]); 70 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 71 | XCTAssertEqualObjects(firstToken, @"ListItem/"); 72 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 73 | XCTAssertEqualObjects(secondToken, @"Online/"); 74 | NSString *thirdToken = [tokenizer tokenAtLevel: 2]; 75 | XCTAssertEqualObjects(thirdToken, @"button"); 76 | } 77 | } 78 | 79 | - (void)testAtFirstLevel 80 | { 81 | { 82 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem/"]; 83 | XCTAssertEqual(tokenizer.count, 1); 84 | 85 | XCTAssertTrue([tokenizer isEndWithDelimeterAtBottomLevel]); 86 | 87 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 88 | XCTAssertEqualObjects(firstToken, @"ListItem/"); 89 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 90 | XCTAssertNil(secondToken); 91 | } 92 | } 93 | 94 | - (void)testSymbolNameSeparatedWithSpaceAndContainsNumber 95 | { 96 | { 97 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem / 1"]; 98 | XCTAssertEqual(tokenizer.count, 2); 99 | XCTAssertFalse([tokenizer isEndWithDelimeterAtBottomLevel]); 100 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 101 | XCTAssertEqualObjects(firstToken, @"ListItem / "); 102 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 103 | XCTAssertEqualObjects(secondToken, @"1"); 104 | } 105 | 106 | { 107 | CSNNameTokenizer *tokenizer = [[CSNNameTokenizer alloc] initWithString:@"ListItem / 1 / 2"]; 108 | XCTAssertEqual(tokenizer.count, 3); 109 | XCTAssertFalse([tokenizer isEndWithDelimeterAtBottomLevel]); 110 | NSString *firstToken = [tokenizer tokenAtLevel: 0]; 111 | XCTAssertEqualObjects(firstToken, @"ListItem / "); 112 | NSString *secondToken = [tokenizer tokenAtLevel: 1]; 113 | XCTAssertEqualObjects(secondToken, @"1 / "); 114 | NSString *thirdToken = [tokenizer tokenAtLevel: 2]; 115 | XCTAssertEqualObjects(thirdToken, @"2"); 116 | } 117 | 118 | } 119 | @end 120 | -------------------------------------------------------------------------------- /SymbolNameAutocompleteTests/CSNSymbolRepositoryTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CSNSymbolRepositoryTests.m 3 | // SymbolNameAutocompleteTests 4 | // 5 | // Created by griffin-stewie on 2018/11/23. 6 | // Copyright © 2018 cyan-stivy.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CSNSymbolRepository.h" 11 | #import "CSNNameTokenizer.h" 12 | #import "CSNFetchResult.h" 13 | #import "CSNSymbolMasterItem.h" 14 | 15 | @interface CSNSymbolRepositoryTests : XCTestCase 16 | @property (nonatomic, strong) CSNSymbolRepository *repository; 17 | @end 18 | 19 | @implementation CSNSymbolRepositoryTests 20 | 21 | - (void)setUp 22 | { 23 | self.repository = [[CSNSymbolRepository alloc] initWithNames:@[ 24 | @"ListItem/Online", 25 | @"ListItem/Offline", 26 | @"StatusBar", 27 | ]]; 28 | } 29 | 30 | - (void)tearDown 31 | { 32 | self.repository = nil; 33 | } 34 | 35 | - (void)testFetchItemsByStringEndWithDelimiter 36 | { 37 | NSString *input = @"ListItem/"; 38 | CSNFetchResult *result = [self.repository fetchItemsByString:input]; 39 | XCTAssertEqual(result.items.count, 2); 40 | } 41 | 42 | - (void)testFetchItemsByStringEndWithFirstLetter 43 | { 44 | NSString *input = @"ListItem/o"; 45 | 46 | CSNFetchResult *result = [self.repository fetchItemsByString:input]; 47 | XCTAssertEqual(result.items.count, 2); 48 | 49 | XCTAssertEqualObjects([result.items[0] tokenAtLevel:result.bottomLevel], @"Online"); 50 | 51 | NSArray *tokens = [result tokensAtBottomLevel]; 52 | XCTAssertEqualObjects(tokens[0], @"Online"); 53 | XCTAssertEqualObjects(tokens[1], @"Offline"); 54 | 55 | } 56 | 57 | - (void)testTokenStringUpToLastLevel 58 | { 59 | 60 | { 61 | NSString *input = @"Li"; 62 | CSNFetchResult *result = [self.repository fetchItemsByString:input]; 63 | XCTAssertEqual(result.items.count, 2); 64 | XCTAssertEqual(result.bottomLevel, 0); 65 | NSArray *names = [result tokenStringUpToBottomLevel]; 66 | XCTAssertEqual(names.count, 1); 67 | XCTAssertEqualObjects(names[0], @"ListItem/"); 68 | } 69 | 70 | { 71 | NSString *input = @"ListItem/o"; 72 | CSNFetchResult *result = [self.repository fetchItemsByString:input]; 73 | XCTAssertEqual(result.items.count, 2); 74 | NSArray *names = [result tokenStringUpToBottomLevel]; 75 | XCTAssertEqual(names.count, 2); 76 | XCTAssertEqualObjects(names[0], @"ListItem/Offline"); 77 | XCTAssertEqualObjects(names[1], @"ListItem/Online"); 78 | } 79 | 80 | } 81 | 82 | - (void)testListUpItemsUsingStringZeroInput 83 | { 84 | 85 | { 86 | NSString *input = @""; 87 | CSNFetchResult *result = [self.repository listUpItemsUsingString:input]; 88 | XCTAssertEqual(result.items.count, 3); 89 | XCTAssertEqual(result.bottomLevel, 0); 90 | NSArray *names = [result tokenStringUpToBottomLevel]; 91 | XCTAssertEqual(names.count, 2); 92 | XCTAssertEqualObjects(names[0], @"ListItem/"); 93 | XCTAssertEqualObjects(names[1], @"StatusBar"); 94 | } 95 | } 96 | 97 | - (void)testListUpItemsUsingStringStartWithOneLetter 98 | { 99 | { 100 | NSString *input = @"L"; 101 | CSNFetchResult *result = [self.repository listUpItemsUsingString:input]; 102 | XCTAssertEqual(result.items.count, 2); 103 | XCTAssertEqual(result.bottomLevel, 0); 104 | NSArray *names = [result tokenStringUpToBottomLevel]; 105 | XCTAssertEqual(names.count, 1); 106 | XCTAssertEqualObjects(names[0], @"ListItem/"); 107 | } 108 | } 109 | 110 | - (void)testListUpItemsUsingStringTopLevel 111 | { 112 | 113 | { 114 | NSString *input = @"ListItem/"; 115 | CSNFetchResult *result = [self.repository listUpItemsUsingString:input]; 116 | XCTAssertEqual(result.items.count, 2); 117 | 118 | XCTAssertTrue([result isTokenEndWithDelimeterAtBottomLevel]); 119 | 120 | NSArray *names = [result tokenStringUpToLevel:result.bottomLevel + 1 unique:YES]; 121 | XCTAssertEqual(names.count, 2); 122 | XCTAssertEqualObjects(names[0], @"ListItem/Offline"); 123 | XCTAssertEqualObjects(names[1], @"ListItem/Online"); 124 | } 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /SymbolNameAutocompleteTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/assets/symbol_name_autocomplete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/docs/assets/symbol_name_autocomplete.gif -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | default_platform(:mac) 2 | 3 | BUILD_DIR = "build" 4 | FRAMEWORK_NAME = "SymbolNameAutocomplete.framework" 5 | PLUGIN_NAME = "SymbolNameAutocomplete.sketchplugin" 6 | 7 | platform :mac do 8 | desc "Build for development" 9 | lane :develop do 10 | xcodebuild( 11 | clean: false, 12 | build: true, 13 | scheme: "SymbolNameAutocomplete", 14 | configuration: "Debug", 15 | xcargs: "CONFIGURATION_BUILD_DIR=#{BUILD_DIR} BUILD_FROM_FASTLANE=true" 16 | ) 17 | 18 | File.expand_path(File.join("..", BUILD_DIR)) 19 | end 20 | 21 | 22 | desc "Build framework" 23 | lane :build do 24 | xcodebuild( 25 | clean: true, 26 | build: true, 27 | scheme: "SymbolNameAutocomplete", 28 | configuration: "Release", 29 | xcargs: "CONFIGURATION_BUILD_DIR=#{BUILD_DIR} BUILD_FROM_FASTLANE=true " 30 | ) 31 | 32 | File.expand_path(File.join("..", BUILD_DIR)) 33 | end 34 | 35 | desc "Package plugin, building framework unless provided" 36 | lane :package do |options| 37 | fastlane_require "fileutils" 38 | 39 | build_dir = options[:build_dir] 40 | puts "opt build_dir #{build_dir}" 41 | unless build_dir 42 | build_dir = build 43 | end 44 | 45 | puts "build_dir => #{build_dir}" 46 | 47 | puts "⚡️" 48 | 49 | plugin_dir = File.join(build_dir, PLUGIN_NAME) 50 | puts plugin_dir 51 | 52 | FileUtils.mkdir_p(plugin_dir) 53 | 54 | contents_dir = File.join(plugin_dir, "Contents") 55 | FileUtils.mkdir_p(contents_dir) 56 | 57 | resources_dir = File.join(contents_dir, "Resources") 58 | FileUtils.mkdir_p(resources_dir) 59 | 60 | framework_dir = File.join(build_dir, FRAMEWORK_NAME) 61 | FileUtils.copy_entry(framework_dir, File.join(resources_dir, FRAMEWORK_NAME)) 62 | 63 | FileUtils.cp("../plugin/img/icon.png", resources_dir) 64 | 65 | sketch_dir = File.join(contents_dir, "Sketch") 66 | FileUtils.mkdir_p(sketch_dir) 67 | 68 | FileUtils.cp("../plugin/manifest.json", sketch_dir) 69 | 70 | dir = File.expand_path(File.join("..", PLUGIN_NAME)) 71 | 72 | if Dir.exist?(dir) 73 | FileUtils.remove_entry_secure(dir) 74 | end 75 | 76 | FileUtils.cp_r(plugin_dir, "..") 77 | dir 78 | end 79 | 80 | desc "Package and install plugin to Sketch" 81 | lane :install do |options| 82 | fastlane_require "fileutils" 83 | 84 | plugin_dir = package(options) 85 | plugin_link = File.join(Dir.home, "Library", "Application Support", "com.bohemiancoding.sketch3", "Plugins", PLUGIN_NAME) 86 | 87 | FileUtils.rm_f(plugin_link) 88 | FileUtils.ln_s(plugin_dir, plugin_link) 89 | end 90 | 91 | desc "Package plugin, and zip it" 92 | lane :zipped_package do |options| 93 | fastlane_require "fileutils" 94 | plugin_dir = package(options) 95 | plugin_compressed_path = "#{plugin_dir}.zip" 96 | FileUtils.rm_f(plugin_compressed_path) 97 | sh("ditto -c -k --rsrc --keepParent \"#{plugin_dir}\" \"#{plugin_compressed_path}\"") 98 | puts plugin_compressed_path 99 | plugin_compressed_path 100 | end 101 | 102 | desc "Publish and Package" 103 | lane :publish do |options| 104 | fastlane_require "fileutils" 105 | fastlane_require "json" 106 | 107 | plugin_dir = package(options) 108 | FileUtils.cp_r(plugin_dir, "..", {:remove_destination => true}) 109 | 110 | version = "" 111 | File.open("../plugin/manifest.json") do |j| 112 | hash = JSON.load(j) 113 | version = hash["version"] 114 | end 115 | 116 | if version.empty? then 117 | UI.error 'version is empty' 118 | next # skip doing the rest of this lane 119 | end 120 | 121 | puts "Current version in manifest.json is #{version}" 122 | 123 | UI.success("Ready to publish. Run command bellow:\nskpm publish #{version}") 124 | end 125 | 126 | desc "Notarize" 127 | lane :notarize_plugin do |options| 128 | fastlane_require "fileutils" 129 | fastlane_require "json" 130 | fastlane_require "yaml" 131 | fastlane_require "zip" 132 | fastlane_require "plist" 133 | fastlane_require "pp" 134 | 135 | skpmrc = YAML.load_file("../.skpmrc") 136 | notarization = skpmrc["notarization"] 137 | 138 | username = notarization["username"] 139 | password = notarization["password"] 140 | 141 | zipfile = File.expand_path(options[:zip], "..") 142 | 143 | bundleID = "" 144 | Zip::File.open(zipfile) do |zip_file| 145 | # Handle entries one by one 146 | zip_file.each do |entry| 147 | if entry.name.end_with?("Info.plist") then 148 | # Read into memory 149 | entry.get_input_stream do |a| 150 | result = Plist.parse_xml(a) 151 | bundleID = result["CFBundleIdentifier"] 152 | end 153 | end 154 | end 155 | end 156 | 157 | if bundleID.empty? then 158 | UI.error 'bundleID is empty' 159 | next # skip doing the rest of this lane 160 | end 161 | 162 | notarization_upload_response = ` 163 | xcrun altool --notarize-app -f #{zipfile} --primary-bundle-id \"#{bundleID}\" -u \"#{username}\" -p \"#{password}\" --output-format xml 164 | ` 165 | # pp notarization_info_response 166 | notarization_upload_plist = Plist.parse_xml(notarization_upload_response) 167 | 168 | if $? != 0 then 169 | if notarization_upload_plist.nil? then 170 | UI.user_error! "Something went wrong" 171 | next 172 | end 173 | 174 | errors = notarization_upload_plist["product-errors"] 175 | unless errors.nil? || errors.empty? then 176 | errors.each do |e| 177 | UI.error e["message"] 178 | end 179 | UI.user_error! "Error" 180 | next 181 | end 182 | end 183 | 184 | UI.message notarization_upload_plist 185 | 186 | notarization_request_id = notarization_upload_plist['notarization-upload']['RequestUUID'] 187 | 188 | UI.success("Successfully uploaded package to notarization service with request identifier #{notarization_request_id}") 189 | 190 | notarization_info = {} 191 | while notarization_info.empty? || (notarization_info['Status'] == 'in progress') 192 | if notarization_info.empty? 193 | UI.message('Waiting to query request status') 194 | end 195 | 196 | sleep(30) 197 | 198 | UI.message('Querying request status') 199 | 200 | notarization_info_response = Actions.sh( 201 | "xcrun altool --notarization-info #{notarization_request_id} -u #{username} -p #{password} --output-format xml", 202 | log: false 203 | ) 204 | 205 | notarization_info_plist = Plist.parse_xml(notarization_info_response) 206 | notarization_info = notarization_info_plist['notarization-info'] 207 | end 208 | 209 | log_url = notarization_info['LogFileURL'] 210 | log_suffix = '' 211 | if log_url 212 | log_response = Net::HTTP.get(URI(log_url)) 213 | log_json_object = JSON.parse(log_response) 214 | log_suffix = ", with log:\n#{JSON.pretty_generate(log_json_object)}" 215 | end 216 | 217 | case notarization_info['Status'] 218 | when 'success' 219 | UI.success("Successfully notarized#{log_suffix}") 220 | when 'invalid' 221 | UI.user_error!("Could not notarize package with message '#{notarization_info['Status Message']}'#{log_suffix}") 222 | else 223 | UI.crash!("Could not notarize package with status '#{notarization_info['Status']}'#{log_suffix}") 224 | end 225 | end 226 | end 227 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew install fastlane` 16 | 17 | # Available Actions 18 | ## Mac 19 | ### mac develop 20 | ``` 21 | fastlane mac develop 22 | ``` 23 | Build for development 24 | ### mac build 25 | ``` 26 | fastlane mac build 27 | ``` 28 | Build framework 29 | ### mac package 30 | ``` 31 | fastlane mac package 32 | ``` 33 | Package plugin, building framework unless provided 34 | ### mac install 35 | ``` 36 | fastlane mac install 37 | ``` 38 | Package and install plugin to Sketch 39 | ### mac zipped_package 40 | ``` 41 | fastlane mac zipped_package 42 | ``` 43 | Package plugin, and zip it 44 | ### mac publish 45 | ``` 46 | fastlane mac publish 47 | ``` 48 | Publish and Package 49 | ### mac notarize_plugin 50 | ``` 51 | fastlane mac notarize_plugin 52 | ``` 53 | Notarize 54 | 55 | ---- 56 | 57 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 58 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 59 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Symbol Name Autocomplete", 3 | "description": "This plugin gives you autocompletion of symbol names when creating a symbol.", 4 | "version": "0.7.0", 5 | "author": "griffin-stewie", 6 | "engines": { 7 | "sketch": ">=49.0" 8 | }, 9 | "skpm": { 10 | "name": "Symbol Name Autocomplete", 11 | "manifest": "plugin/manifest.json", 12 | "main": "SymbolNameAutocomplete.sketchplugin", 13 | "repository": "https://github.com/griffin-stewie/SymbolNameAutocomplete", 14 | "description": "This Sketch plugin gives you autocompletion of symbol names when creating a symbol" 15 | }, 16 | "devDependencies": { 17 | "@skpm/builder": "^0.7.0" 18 | }, 19 | "scripts": { 20 | "postinstall": "npm run build && skpm-link", 21 | "fastlane": "bundle exec fastlane mac package", 22 | "build": "npm run fastlane && skpm-build" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /plugin/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/plugin/img/icon.png -------------------------------------------------------------------------------- /plugin/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://github.com/griffin-stewie/SymbolNameAutocomplete", 3 | "identifier": "net.cyan-stivy.sketchPlugin.symbol-name-autocomplete", 4 | "icon": "icon.png", 5 | "appcast": "https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/master/.appcast.xml", 6 | "compatibleVersion": 3, 7 | "bundleVersion": 1, 8 | "commands": [ 9 | { 10 | "name": "Handle Actions", 11 | "identifier": "handle-actions", 12 | "script": "./src/index.js", 13 | "handlers": { 14 | "actions": { 15 | "Startup": "onStartup", 16 | "Shutdown": "onShutdown", 17 | "CreateSymbol.finish": "onCreateSymbolDidAppearHandler" 18 | } 19 | } 20 | }, 21 | { 22 | "name": "About Symbol Name Autocomplete", 23 | "identifier": "about", 24 | "script": "./src/index.js", 25 | "handler": "onSelectAboutMenuItem", 26 | "description": "Learn more about the Symbol Name Autocomplete plugin." 27 | } 28 | ], 29 | "menu": { 30 | "items": [ 31 | "about" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /plugin/src/index.js: -------------------------------------------------------------------------------- 1 | var REPOSITORY_URL_STRING = "https://github.com/griffin-stewie/SymbolNameAutocomplete"; 2 | 3 | /** 4 | * Handles startup action. 5 | */ 6 | export function onStartup(context) { 7 | if (!isFrameworkLoaded()) { 8 | var contentsPath = context.scriptPath.stringByDeletingLastPathComponent().stringByDeletingLastPathComponent(); 9 | var resourcesPath = contentsPath.stringByAppendingPathComponent("Resources"); 10 | 11 | var result = Mocha.sharedRuntime().loadFrameworkWithName_inDirectory("SymbolNameAutocomplete", resourcesPath); 12 | if (!result) { 13 | var alert = NSAlert.alloc().init(); 14 | alert.alertStyle = NSAlertStyleCritical; 15 | alert.messageText = "Loading framework for “Symbol Name Autocomplete” failed" 16 | alert.informativeText = "Please try disabling and enabling the plugin or restarting Sketch." 17 | 18 | alert.runModal(); 19 | 20 | return; 21 | } 22 | } 23 | 24 | log("SymbolNameAutocompletePluginController Enabled"); 25 | SymbolNameAutocompletePluginController.sharedController().enabled = true; 26 | } 27 | 28 | /** 29 | * Handles shutdown action. 30 | */ 31 | export function onShutdown(context) { 32 | if (isFrameworkLoaded()) { 33 | log("SymbolNameAutocompletePluginController Disabled"); 34 | SymbolNameAutocompletePluginController.sharedController().enabled = false; 35 | } 36 | } 37 | 38 | /** 39 | * Handles CreateSymbol.finish action. 40 | */ 41 | export function onCreateSymbolDidAppearHandler(context) { 42 | if (isFrameworkLoaded()) { 43 | const doc = context.actionContext.document; 44 | const docData = doc.documentData(); 45 | const allMasterSymbols = docData.allSymbols(); 46 | log(allMasterSymbols); 47 | const window = doc.window(); 48 | const sheetWindow = window.attachedSheet(); 49 | const createSymbolNameingSheet = sheetWindow.windowController(); 50 | log("SymbolNameAutocompletePluginController Passing Sheet instance"); 51 | SymbolNameAutocompletePluginController.sharedController().namingSheet = createSymbolNameingSheet; 52 | SymbolNameAutocompletePluginController.sharedController().documentData = docData; 53 | } 54 | } 55 | 56 | 57 | function isFrameworkLoaded() { 58 | return Boolean(NSClassFromString("SymbolNameAutocompletePluginController")); 59 | } 60 | 61 | /** 62 | * Handles about menu item. 63 | */ 64 | export function onSelectAboutMenuItem(context) { 65 | var repositoryUrl = NSURL.URLWithString(REPOSITORY_URL_STRING); 66 | 67 | NSWorkspace.sharedWorkspace().openURL(repositoryUrl); 68 | } -------------------------------------------------------------------------------- /vendor/cache/CFPropertyList-3.0.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/CFPropertyList-3.0.3.gem -------------------------------------------------------------------------------- /vendor/cache/addressable-2.8.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/addressable-2.8.0.gem -------------------------------------------------------------------------------- /vendor/cache/artifactory-3.0.15.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/artifactory-3.0.15.gem -------------------------------------------------------------------------------- /vendor/cache/atomos-0.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/atomos-0.1.3.gem -------------------------------------------------------------------------------- /vendor/cache/aws-eventstream-1.1.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/aws-eventstream-1.1.1.gem -------------------------------------------------------------------------------- /vendor/cache/aws-partitions-1.473.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/aws-partitions-1.473.0.gem -------------------------------------------------------------------------------- /vendor/cache/aws-sdk-core-3.115.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/aws-sdk-core-3.115.0.gem -------------------------------------------------------------------------------- /vendor/cache/aws-sdk-kms-1.44.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/aws-sdk-kms-1.44.0.gem -------------------------------------------------------------------------------- /vendor/cache/aws-sdk-s3-1.96.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/aws-sdk-s3-1.96.1.gem -------------------------------------------------------------------------------- /vendor/cache/aws-sigv4-1.2.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/aws-sigv4-1.2.3.gem -------------------------------------------------------------------------------- /vendor/cache/babosa-1.0.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/babosa-1.0.4.gem -------------------------------------------------------------------------------- /vendor/cache/claide-1.0.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/claide-1.0.3.gem -------------------------------------------------------------------------------- /vendor/cache/colored-1.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/colored-1.2.gem -------------------------------------------------------------------------------- /vendor/cache/colored2-3.1.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/colored2-3.1.2.gem -------------------------------------------------------------------------------- /vendor/cache/commander-4.6.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/commander-4.6.0.gem -------------------------------------------------------------------------------- /vendor/cache/declarative-0.0.20.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/declarative-0.0.20.gem -------------------------------------------------------------------------------- /vendor/cache/digest-crc-0.6.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/digest-crc-0.6.3.gem -------------------------------------------------------------------------------- /vendor/cache/domain_name-0.5.20190701.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/domain_name-0.5.20190701.gem -------------------------------------------------------------------------------- /vendor/cache/dotenv-2.7.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/dotenv-2.7.6.gem -------------------------------------------------------------------------------- /vendor/cache/emoji_regex-3.2.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/emoji_regex-3.2.2.gem -------------------------------------------------------------------------------- /vendor/cache/excon-0.83.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/excon-0.83.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-1.5.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-1.5.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-cookie_jar-0.0.7.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-cookie_jar-0.0.7.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-em_http-1.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-em_http-1.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-em_synchrony-1.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-em_synchrony-1.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-excon-1.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-excon-1.1.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-httpclient-1.0.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-httpclient-1.0.1.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-net_http-1.0.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-net_http-1.0.1.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-net_http_persistent-1.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-net_http_persistent-1.1.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-patron-1.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday-patron-1.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/faraday_middleware-1.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/faraday_middleware-1.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/fastimage-2.2.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/fastimage-2.2.4.gem -------------------------------------------------------------------------------- /vendor/cache/fastlane-2.187.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/fastlane-2.187.0.gem -------------------------------------------------------------------------------- /vendor/cache/gh_inspector-1.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/gh_inspector-1.1.3.gem -------------------------------------------------------------------------------- /vendor/cache/google-apis-androidpublisher_v3-0.8.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-apis-androidpublisher_v3-0.8.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-apis-core-0.4.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-apis-core-0.4.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-apis-iamcredentials_v1-0.6.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-apis-iamcredentials_v1-0.6.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-apis-playcustomapp_v1-0.5.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-apis-playcustomapp_v1-0.5.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-apis-storage_v1-0.6.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-apis-storage_v1-0.6.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-cloud-core-1.6.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-cloud-core-1.6.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-cloud-env-1.5.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-cloud-env-1.5.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-cloud-errors-1.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-cloud-errors-1.1.0.gem -------------------------------------------------------------------------------- /vendor/cache/google-cloud-storage-1.34.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/google-cloud-storage-1.34.0.gem -------------------------------------------------------------------------------- /vendor/cache/googleauth-0.16.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/googleauth-0.16.2.gem -------------------------------------------------------------------------------- /vendor/cache/highline-2.0.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/highline-2.0.3.gem -------------------------------------------------------------------------------- /vendor/cache/http-cookie-1.0.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/http-cookie-1.0.4.gem -------------------------------------------------------------------------------- /vendor/cache/httpclient-2.8.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/httpclient-2.8.3.gem -------------------------------------------------------------------------------- /vendor/cache/jmespath-1.4.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/jmespath-1.4.0.gem -------------------------------------------------------------------------------- /vendor/cache/json-2.5.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/json-2.5.1.gem -------------------------------------------------------------------------------- /vendor/cache/jwt-2.2.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/jwt-2.2.3.gem -------------------------------------------------------------------------------- /vendor/cache/memoist-0.16.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/memoist-0.16.2.gem -------------------------------------------------------------------------------- /vendor/cache/mini_magick-4.11.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/mini_magick-4.11.0.gem -------------------------------------------------------------------------------- /vendor/cache/mini_mime-1.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/mini_mime-1.1.0.gem -------------------------------------------------------------------------------- /vendor/cache/multi_json-1.15.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/multi_json-1.15.0.gem -------------------------------------------------------------------------------- /vendor/cache/multipart-post-2.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/multipart-post-2.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/nanaimo-0.3.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/nanaimo-0.3.0.gem -------------------------------------------------------------------------------- /vendor/cache/naturally-2.2.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/naturally-2.2.1.gem -------------------------------------------------------------------------------- /vendor/cache/os-1.1.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/os-1.1.1.gem -------------------------------------------------------------------------------- /vendor/cache/plist-3.6.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/plist-3.6.0.gem -------------------------------------------------------------------------------- /vendor/cache/public_suffix-4.0.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/public_suffix-4.0.6.gem -------------------------------------------------------------------------------- /vendor/cache/rake-13.0.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/rake-13.0.4.gem -------------------------------------------------------------------------------- /vendor/cache/representable-3.1.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/representable-3.1.1.gem -------------------------------------------------------------------------------- /vendor/cache/retriable-3.1.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/retriable-3.1.2.gem -------------------------------------------------------------------------------- /vendor/cache/rexml-3.2.5.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/rexml-3.2.5.gem -------------------------------------------------------------------------------- /vendor/cache/rouge-2.0.7.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/rouge-2.0.7.gem -------------------------------------------------------------------------------- /vendor/cache/ruby2_keywords-0.0.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/ruby2_keywords-0.0.4.gem -------------------------------------------------------------------------------- /vendor/cache/rubyzip-2.3.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/rubyzip-2.3.2.gem -------------------------------------------------------------------------------- /vendor/cache/security-0.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/security-0.1.3.gem -------------------------------------------------------------------------------- /vendor/cache/signet-0.15.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/signet-0.15.0.gem -------------------------------------------------------------------------------- /vendor/cache/simctl-1.6.8.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/simctl-1.6.8.gem -------------------------------------------------------------------------------- /vendor/cache/terminal-notifier-2.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/terminal-notifier-2.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/terminal-table-1.8.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/terminal-table-1.8.0.gem -------------------------------------------------------------------------------- /vendor/cache/trailblazer-option-0.1.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/trailblazer-option-0.1.1.gem -------------------------------------------------------------------------------- /vendor/cache/tty-cursor-0.7.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/tty-cursor-0.7.1.gem -------------------------------------------------------------------------------- /vendor/cache/tty-screen-0.8.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/tty-screen-0.8.1.gem -------------------------------------------------------------------------------- /vendor/cache/tty-spinner-0.9.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/tty-spinner-0.9.3.gem -------------------------------------------------------------------------------- /vendor/cache/uber-0.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/uber-0.1.0.gem -------------------------------------------------------------------------------- /vendor/cache/unf-0.1.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/unf-0.1.4.gem -------------------------------------------------------------------------------- /vendor/cache/unf_ext-0.0.7.7.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/unf_ext-0.0.7.7.gem -------------------------------------------------------------------------------- /vendor/cache/unicode-display_width-1.7.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/unicode-display_width-1.7.0.gem -------------------------------------------------------------------------------- /vendor/cache/webrick-1.7.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/webrick-1.7.0.gem -------------------------------------------------------------------------------- /vendor/cache/word_wrap-1.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/word_wrap-1.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/xcodeproj-1.20.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/xcodeproj-1.20.0.gem -------------------------------------------------------------------------------- /vendor/cache/xcpretty-0.3.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/xcpretty-0.3.0.gem -------------------------------------------------------------------------------- /vendor/cache/xcpretty-travis-formatter-1.0.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/griffin-stewie/SymbolNameAutocomplete/38c7b0d645932ba58e86a0a1c89172c0d0309ed0/vendor/cache/xcpretty-travis-formatter-1.0.1.gem --------------------------------------------------------------------------------