├── .gitignore
├── DTXcodeUtils.podspec
├── Example
├── .gitignore
├── Example.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── Example.xcworkspace
│ └── contents.xcworkspacedata
├── Example
│ ├── DTExample.h
│ ├── DTExample.m
│ ├── Example-Info.plist
│ ├── Example-Prefix.pch
│ └── en.lproj
│ │ └── InfoPlist.strings
└── Podfile
├── LICENSE
├── Pod
├── Classes
│ ├── .gitkeep
│ ├── DTXcodeUtils.h
│ └── DTXcodeUtils.m
└── XcodeHeaders
│ └── DTXcodeHeaders.h
├── README.md
└── XcodeHeaders.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | # We recommend against adding the Pods directory to your .gitignore. However
26 | # you should judge for yourself, the pros and cons are mentioned at:
27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
28 | #
29 | # Note: if you ignore the Pods directory, make sure to uncomment
30 | # `pod install` in .travis.yml
31 | #
32 | # Pods/
33 |
--------------------------------------------------------------------------------
/DTXcodeUtils.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "DTXcodeUtils"
3 | s.deprecated = true
4 | s.version = "0.1.1"
5 | s.summary = "Useful helper functions for writing Xcode plugins"
6 | s.homepage = "https://github.com/thurn/DTXcodeUtils"
7 | s.license = 'Creative Commons Zero'
8 | s.author = { "Derek Thurn" => "derek@fake.email" }
9 | s.source = { :git => "https://github.com/thurn/DTXcodeUtils.git", :tag => s.version.to_s }
10 |
11 | s.platform = :osx
12 | s.requires_arc = true
13 |
14 | s.source_files = 'Pod/Classes/**/*.{h,m}', 'Pod/XcodeHeaders/**/*.h'
15 | end
16 |
--------------------------------------------------------------------------------
/Example/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | .DS_Store
3 | .Trashes
4 | *.swp
5 | *.lock
6 | *~.nib
7 | DerivedData/
8 | build/
9 | *.pbxuser
10 | *.mode1v3
11 | *.mode2v3
12 | *.perspectivev3
13 | !default.pbxuser
14 | !default.mode1v3
15 | !default.mode2v3
16 | !default.perspectivev3
17 | xcuserdata
18 | *.moved-aside
19 | Pods/
20 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | archiveVersion
6 | 1
7 | classes
8 |
9 | objectVersion
10 | 46
11 | objects
12 |
13 | 17A62964667C4A58A53684F8
14 |
15 | buildActionMask
16 | 2147483647
17 | files
18 |
19 | inputPaths
20 |
21 | isa
22 | PBXShellScriptBuildPhase
23 | name
24 | Check Pods Manifest.lock
25 | outputPaths
26 |
27 | runOnlyForDeploymentPostprocessing
28 | 0
29 | shellPath
30 | /bin/sh
31 | shellScript
32 | diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null
33 | if [[ $? != 0 ]] ; then
34 | cat << EOM
35 | error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
36 | EOM
37 | exit 1
38 | fi
39 |
40 | showEnvVarsInLog
41 | 0
42 |
43 | 61BDFE5F61124E5F8218F0EF
44 |
45 | fileRef
46 | F8C7CFACE9CB4A1E842D5907
47 | isa
48 | PBXBuildFile
49 |
50 | 7CD9185919A7B46F00B814F8
51 |
52 | children
53 |
54 | 7CD9186919A7B46F00B814F8
55 | 7CD9186419A7B46F00B814F8
56 | 7CD9186319A7B46F00B814F8
57 | 8137908705E64CAA935259DF
58 |
59 | isa
60 | PBXGroup
61 | sourceTree
62 | <group>
63 |
64 | 7CD9185A19A7B46F00B814F8
65 |
66 | attributes
67 |
68 | CLASSPREFIX
69 | DT
70 | LastUpgradeCheck
71 | 0510
72 |
73 | buildConfigurationList
74 | 7CD9185D19A7B46F00B814F8
75 | compatibilityVersion
76 | Xcode 3.2
77 | developmentRegion
78 | English
79 | hasScannedForEncodings
80 | 0
81 | isa
82 | PBXProject
83 | knownRegions
84 |
85 | en
86 |
87 | mainGroup
88 | 7CD9185919A7B46F00B814F8
89 | productRefGroup
90 | 7CD9186319A7B46F00B814F8
91 | projectDirPath
92 |
93 | projectReferences
94 |
95 | projectRoot
96 |
97 | targets
98 |
99 | 7CD9186119A7B46F00B814F8
100 |
101 |
102 | 7CD9185D19A7B46F00B814F8
103 |
104 | buildConfigurations
105 |
106 | 7CD9187319A7B46F00B814F8
107 | 7CD9187419A7B46F00B814F8
108 |
109 | defaultConfigurationIsVisible
110 | 0
111 | defaultConfigurationName
112 | Release
113 | isa
114 | XCConfigurationList
115 |
116 | 7CD9185E19A7B46F00B814F8
117 |
118 | buildActionMask
119 | 2147483647
120 | files
121 |
122 | 7CD9187119A7B46F00B814F8
123 |
124 | isa
125 | PBXSourcesBuildPhase
126 | runOnlyForDeploymentPostprocessing
127 | 0
128 |
129 | 7CD9185F19A7B46F00B814F8
130 |
131 | buildActionMask
132 | 2147483647
133 | files
134 |
135 | 7CD9186619A7B46F00B814F8
136 | 7CD9186819A7B46F00B814F8
137 | 61BDFE5F61124E5F8218F0EF
138 |
139 | isa
140 | PBXFrameworksBuildPhase
141 | runOnlyForDeploymentPostprocessing
142 | 0
143 |
144 | 7CD9186019A7B46F00B814F8
145 |
146 | buildActionMask
147 | 2147483647
148 | files
149 |
150 | 7CD9186E19A7B46F00B814F8
151 |
152 | isa
153 | PBXResourcesBuildPhase
154 | runOnlyForDeploymentPostprocessing
155 | 0
156 |
157 | 7CD9186119A7B46F00B814F8
158 |
159 | buildConfigurationList
160 | 7CD9187519A7B46F00B814F8
161 | buildPhases
162 |
163 | 17A62964667C4A58A53684F8
164 | 7CD9185E19A7B46F00B814F8
165 | 7CD9185F19A7B46F00B814F8
166 | 7CD9186019A7B46F00B814F8
167 | B5CB82C51FF641CE9A74FAFC
168 |
169 | buildRules
170 |
171 | dependencies
172 |
173 | isa
174 | PBXNativeTarget
175 | name
176 | Example
177 | productName
178 | Example
179 | productReference
180 | 7CD9186219A7B46F00B814F8
181 | productType
182 | com.apple.product-type.bundle
183 |
184 | 7CD9186219A7B46F00B814F8
185 |
186 | explicitFileType
187 | wrapper.cfbundle
188 | includeInIndex
189 | 0
190 | isa
191 | PBXFileReference
192 | path
193 | Example.xcplugin
194 | sourceTree
195 | BUILT_PRODUCTS_DIR
196 |
197 | 7CD9186319A7B46F00B814F8
198 |
199 | children
200 |
201 | 7CD9186219A7B46F00B814F8
202 |
203 | isa
204 | PBXGroup
205 | name
206 | Products
207 | sourceTree
208 | <group>
209 |
210 | 7CD9186419A7B46F00B814F8
211 |
212 | children
213 |
214 | 7CD9186519A7B46F00B814F8
215 | 7CD9186719A7B46F00B814F8
216 | F8C7CFACE9CB4A1E842D5907
217 |
218 | isa
219 | PBXGroup
220 | name
221 | Frameworks
222 | sourceTree
223 | <group>
224 |
225 | 7CD9186519A7B46F00B814F8
226 |
227 | isa
228 | PBXFileReference
229 | lastKnownFileType
230 | wrapper.framework
231 | name
232 | AppKit.framework
233 | path
234 | System/Library/Frameworks/AppKit.framework
235 | sourceTree
236 | SDKROOT
237 |
238 | 7CD9186619A7B46F00B814F8
239 |
240 | fileRef
241 | 7CD9186519A7B46F00B814F8
242 | isa
243 | PBXBuildFile
244 |
245 | 7CD9186719A7B46F00B814F8
246 |
247 | isa
248 | PBXFileReference
249 | lastKnownFileType
250 | wrapper.framework
251 | name
252 | Foundation.framework
253 | path
254 | System/Library/Frameworks/Foundation.framework
255 | sourceTree
256 | SDKROOT
257 |
258 | 7CD9186819A7B46F00B814F8
259 |
260 | fileRef
261 | 7CD9186719A7B46F00B814F8
262 | isa
263 | PBXBuildFile
264 |
265 | 7CD9186919A7B46F00B814F8
266 |
267 | children
268 |
269 | 7CD9186F19A7B46F00B814F8
270 | 7CD9187019A7B46F00B814F8
271 | 7CD9186A19A7B46F00B814F8
272 |
273 | isa
274 | PBXGroup
275 | path
276 | Example
277 | sourceTree
278 | <group>
279 |
280 | 7CD9186A19A7B46F00B814F8
281 |
282 | children
283 |
284 | 7CD9186B19A7B46F00B814F8
285 | 7CD9186C19A7B46F00B814F8
286 | 7CD9187219A7B46F00B814F8
287 |
288 | isa
289 | PBXGroup
290 | name
291 | Supporting Files
292 | sourceTree
293 | <group>
294 |
295 | 7CD9186B19A7B46F00B814F8
296 |
297 | isa
298 | PBXFileReference
299 | lastKnownFileType
300 | text.plist.xml
301 | path
302 | Example-Info.plist
303 | sourceTree
304 | <group>
305 |
306 | 7CD9186C19A7B46F00B814F8
307 |
308 | children
309 |
310 | 7CD9186D19A7B46F00B814F8
311 |
312 | isa
313 | PBXVariantGroup
314 | name
315 | InfoPlist.strings
316 | sourceTree
317 | <group>
318 |
319 | 7CD9186D19A7B46F00B814F8
320 |
321 | isa
322 | PBXFileReference
323 | lastKnownFileType
324 | text.plist.strings
325 | name
326 | en
327 | path
328 | en.lproj/InfoPlist.strings
329 | sourceTree
330 | <group>
331 |
332 | 7CD9186E19A7B46F00B814F8
333 |
334 | fileRef
335 | 7CD9186C19A7B46F00B814F8
336 | isa
337 | PBXBuildFile
338 |
339 | 7CD9186F19A7B46F00B814F8
340 |
341 | isa
342 | PBXFileReference
343 | lastKnownFileType
344 | sourcecode.c.h
345 | path
346 | DTExample.h
347 | sourceTree
348 | <group>
349 |
350 | 7CD9187019A7B46F00B814F8
351 |
352 | isa
353 | PBXFileReference
354 | lastKnownFileType
355 | sourcecode.c.objc
356 | path
357 | DTExample.m
358 | sourceTree
359 | <group>
360 |
361 | 7CD9187119A7B46F00B814F8
362 |
363 | fileRef
364 | 7CD9187019A7B46F00B814F8
365 | isa
366 | PBXBuildFile
367 |
368 | 7CD9187219A7B46F00B814F8
369 |
370 | isa
371 | PBXFileReference
372 | lastKnownFileType
373 | sourcecode.c.h
374 | path
375 | Example-Prefix.pch
376 | sourceTree
377 | <group>
378 |
379 | 7CD9187319A7B46F00B814F8
380 |
381 | buildSettings
382 |
383 | ALWAYS_SEARCH_USER_PATHS
384 | NO
385 | CLANG_CXX_LANGUAGE_STANDARD
386 | gnu++0x
387 | CLANG_CXX_LIBRARY
388 | libc++
389 | CLANG_ENABLE_MODULES
390 | YES
391 | CLANG_ENABLE_OBJC_ARC
392 | YES
393 | CLANG_WARN_BOOL_CONVERSION
394 | YES
395 | CLANG_WARN_CONSTANT_CONVERSION
396 | YES
397 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE
398 | YES_ERROR
399 | CLANG_WARN_EMPTY_BODY
400 | YES
401 | CLANG_WARN_ENUM_CONVERSION
402 | YES
403 | CLANG_WARN_INT_CONVERSION
404 | YES
405 | CLANG_WARN_OBJC_ROOT_CLASS
406 | YES_ERROR
407 | CLANG_WARN__DUPLICATE_METHOD_MATCH
408 | YES
409 | COPY_PHASE_STRIP
410 | NO
411 | GCC_C_LANGUAGE_STANDARD
412 | gnu99
413 | GCC_DYNAMIC_NO_PIC
414 | NO
415 | GCC_ENABLE_OBJC_EXCEPTIONS
416 | YES
417 | GCC_OPTIMIZATION_LEVEL
418 | 0
419 | GCC_PREPROCESSOR_DEFINITIONS
420 |
421 | DEBUG=1
422 | $(inherited)
423 |
424 | GCC_SYMBOLS_PRIVATE_EXTERN
425 | NO
426 | GCC_WARN_64_TO_32_BIT_CONVERSION
427 | YES
428 | GCC_WARN_ABOUT_RETURN_TYPE
429 | YES_ERROR
430 | GCC_WARN_UNDECLARED_SELECTOR
431 | YES
432 | GCC_WARN_UNINITIALIZED_AUTOS
433 | YES_AGGRESSIVE
434 | GCC_WARN_UNUSED_FUNCTION
435 | YES
436 | GCC_WARN_UNUSED_VARIABLE
437 | YES
438 | MACOSX_DEPLOYMENT_TARGET
439 | 10.9
440 | ONLY_ACTIVE_ARCH
441 | YES
442 | SDKROOT
443 | macosx
444 |
445 | isa
446 | XCBuildConfiguration
447 | name
448 | Debug
449 |
450 | 7CD9187419A7B46F00B814F8
451 |
452 | buildSettings
453 |
454 | ALWAYS_SEARCH_USER_PATHS
455 | NO
456 | CLANG_CXX_LANGUAGE_STANDARD
457 | gnu++0x
458 | CLANG_CXX_LIBRARY
459 | libc++
460 | CLANG_ENABLE_MODULES
461 | YES
462 | CLANG_ENABLE_OBJC_ARC
463 | YES
464 | CLANG_WARN_BOOL_CONVERSION
465 | YES
466 | CLANG_WARN_CONSTANT_CONVERSION
467 | YES
468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE
469 | YES_ERROR
470 | CLANG_WARN_EMPTY_BODY
471 | YES
472 | CLANG_WARN_ENUM_CONVERSION
473 | YES
474 | CLANG_WARN_INT_CONVERSION
475 | YES
476 | CLANG_WARN_OBJC_ROOT_CLASS
477 | YES_ERROR
478 | CLANG_WARN__DUPLICATE_METHOD_MATCH
479 | YES
480 | COPY_PHASE_STRIP
481 | YES
482 | DEBUG_INFORMATION_FORMAT
483 | dwarf-with-dsym
484 | ENABLE_NS_ASSERTIONS
485 | NO
486 | GCC_C_LANGUAGE_STANDARD
487 | gnu99
488 | GCC_ENABLE_OBJC_EXCEPTIONS
489 | YES
490 | GCC_WARN_64_TO_32_BIT_CONVERSION
491 | YES
492 | GCC_WARN_ABOUT_RETURN_TYPE
493 | YES_ERROR
494 | GCC_WARN_UNDECLARED_SELECTOR
495 | YES
496 | GCC_WARN_UNINITIALIZED_AUTOS
497 | YES_AGGRESSIVE
498 | GCC_WARN_UNUSED_FUNCTION
499 | YES
500 | GCC_WARN_UNUSED_VARIABLE
501 | YES
502 | MACOSX_DEPLOYMENT_TARGET
503 | 10.9
504 | SDKROOT
505 | macosx
506 |
507 | isa
508 | XCBuildConfiguration
509 | name
510 | Release
511 |
512 | 7CD9187519A7B46F00B814F8
513 |
514 | buildConfigurations
515 |
516 | 7CD9187619A7B46F00B814F8
517 | 7CD9187719A7B46F00B814F8
518 |
519 | defaultConfigurationIsVisible
520 | 0
521 | isa
522 | XCConfigurationList
523 |
524 | 7CD9187619A7B46F00B814F8
525 |
526 | baseConfigurationReference
527 | 8137908705E64CAA935259DF
528 | buildSettings
529 |
530 | COMBINE_HIDPI_IMAGES
531 | YES
532 | DEPLOYMENT_LOCATION
533 | YES
534 | DSTROOT
535 | $(HOME)
536 | GCC_PRECOMPILE_PREFIX_HEADER
537 | YES
538 | GCC_PREFIX_HEADER
539 | Example/Example-Prefix.pch
540 | INFOPLIST_FILE
541 | Example/Example-Info.plist
542 | INSTALL_PATH
543 | /Library/Application Support/Developer/Shared/Xcode/Plug-ins
544 | PRODUCT_NAME
545 | $(TARGET_NAME)
546 | WRAPPER_EXTENSION
547 | xcplugin
548 |
549 | isa
550 | XCBuildConfiguration
551 | name
552 | Debug
553 |
554 | 7CD9187719A7B46F00B814F8
555 |
556 | baseConfigurationReference
557 | 8137908705E64CAA935259DF
558 | buildSettings
559 |
560 | COMBINE_HIDPI_IMAGES
561 | YES
562 | DEPLOYMENT_LOCATION
563 | YES
564 | DSTROOT
565 | $(HOME)
566 | GCC_PRECOMPILE_PREFIX_HEADER
567 | YES
568 | GCC_PREFIX_HEADER
569 | Example/Example-Prefix.pch
570 | INFOPLIST_FILE
571 | Example/Example-Info.plist
572 | INSTALL_PATH
573 | /Library/Application Support/Developer/Shared/Xcode/Plug-ins
574 | PRODUCT_NAME
575 | $(TARGET_NAME)
576 | WRAPPER_EXTENSION
577 | xcplugin
578 |
579 | isa
580 | XCBuildConfiguration
581 | name
582 | Release
583 |
584 | 8137908705E64CAA935259DF
585 |
586 | includeInIndex
587 | 1
588 | isa
589 | PBXFileReference
590 | lastKnownFileType
591 | text.xcconfig
592 | name
593 | Pods-Example.xcconfig
594 | path
595 | Pods/Pods-Example.xcconfig
596 | sourceTree
597 | <group>
598 |
599 | B5CB82C51FF641CE9A74FAFC
600 |
601 | buildActionMask
602 | 2147483647
603 | files
604 |
605 | inputPaths
606 |
607 | isa
608 | PBXShellScriptBuildPhase
609 | name
610 | Copy Pods Resources
611 | outputPaths
612 |
613 | runOnlyForDeploymentPostprocessing
614 | 0
615 | shellPath
616 | /bin/sh
617 | shellScript
618 | "${SRCROOT}/Pods/Pods-Example-resources.sh"
619 |
620 | showEnvVarsInLog
621 | 0
622 |
623 | F8C7CFACE9CB4A1E842D5907
624 |
625 | explicitFileType
626 | archive.ar
627 | includeInIndex
628 | 0
629 | isa
630 | PBXFileReference
631 | path
632 | libPods-Example.a
633 | sourceTree
634 | BUILT_PRODUCTS_DIR
635 |
636 |
637 | rootObject
638 | 7CD9185A19A7B46F00B814F8
639 |
640 |
641 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/Example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Example/Example/DTExample.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface DTExample : NSObject
4 |
5 | @end
--------------------------------------------------------------------------------
/Example/Example/DTExample.m:
--------------------------------------------------------------------------------
1 | #import "DTExample.h"
2 |
3 | #import "DTXcodeHeaders.h"
4 | #import "DTXcodeUtils.h"
5 |
6 | static DTExample *sharedPlugin;
7 |
8 | @interface DTExample()
9 | @property (nonatomic) BOOL highlightingEnabled;
10 | @property (nonatomic, strong) NSBundle *bundle;
11 | @end
12 |
13 | @implementation DTExample
14 |
15 | + (void)pluginDidLoad:(NSBundle *)plugin {
16 | static dispatch_once_t onceToken;
17 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
18 | if ([currentApplicationName isEqual:@"Xcode"]) {
19 | dispatch_once(&onceToken, ^{ sharedPlugin = [[self alloc] initWithBundle:plugin]; });
20 | }
21 | }
22 |
23 | - (id)initWithBundle:(NSBundle *)plugin {
24 | if (self = [super init]) {
25 | _bundle = plugin;
26 | _highlightingEnabled = YES;
27 | NSMenuItem *menuItem = [DTXcodeUtils getMainMenuItemWithTitle:@"Edit"];
28 | if (menuItem) {
29 | [[menuItem submenu] addItem:[NSMenuItem separatorItem]];
30 | NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Highlighting"
31 | action:@selector(doMenuAction)
32 | keyEquivalent:@""];
33 | [actionMenuItem setTarget:self];
34 | [[menuItem submenu] addItem:actionMenuItem];
35 | }
36 | }
37 | return self;
38 | }
39 |
40 | - (void)doMenuAction {
41 | DVTTextStorage *storage = [DTXcodeUtils currentTextStorage];
42 | _highlightingEnabled = !_highlightingEnabled;
43 | storage.syntaxColoringEnabled = _highlightingEnabled;
44 | DVTSourceTextView *textView = [DTXcodeUtils currentSourceTextView];
45 | [textView setNeedsDisplay:YES];
46 | }
47 |
48 | - (void)dealloc {
49 | [[NSNotificationCenter defaultCenter] removeObserver:self];
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/Example/Example/Example-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.example.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | DVTPlugInCompatibilityUUIDs
26 |
27 | 640F884E-CE55-4B40-87C0-8869546CAB7A
28 | 37B30044-3B14-46BA-ABAA-F01000C27B63
29 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED
30 |
31 | NSPrincipalClass
32 | DTExample
33 | XC4Compatible
34 |
35 | XC5Compatible
36 |
37 | XCGCReady
38 |
39 | XCPluginHasUI
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Example/Example/Example-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #endif
10 |
--------------------------------------------------------------------------------
/Example/Example/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | platform :osx
2 |
3 | target "Example" do
4 | pod "DTXcodeUtils", :path => "../"
5 | end
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Except where otherwise noted, all files are released under the
2 | Creative Commons Zero license:
3 |
4 | CC0 1.0 Universal
5 |
6 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
7 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
8 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
9 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
10 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
11 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
12 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
13 | HEREUNDER.
14 |
15 | Statement of Purpose
16 |
17 | The laws of most jurisdictions throughout the world automatically confer
18 | exclusive Copyright and Related Rights (defined below) upon the creator
19 | and subsequent owner(s) (each and all, an "owner") of an original work of
20 | authorship and/or a database (each, a "Work").
21 |
22 | Certain owners wish to permanently relinquish those rights to a Work for
23 | the purpose of contributing to a commons of creative, cultural and
24 | scientific works ("Commons") that the public can reliably and without fear
25 | of later claims of infringement build upon, modify, incorporate in other
26 | works, reuse and redistribute as freely as possible in any form whatsoever
27 | and for any purposes, including without limitation commercial purposes.
28 | These owners may contribute to the Commons to promote the ideal of a free
29 | culture and the further production of creative, cultural and scientific
30 | works, or to gain reputation or greater distribution for their Work in
31 | part through the use and efforts of others.
32 |
33 | For these and/or other purposes and motivations, and without any
34 | expectation of additional consideration or compensation, the person
35 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she
36 | is an owner of Copyright and Related Rights in the Work, voluntarily
37 | elects to apply CC0 to the Work and publicly distribute the Work under its
38 | terms, with knowledge of his or her Copyright and Related Rights in the
39 | Work and the meaning and intended legal effect of CC0 on those rights.
40 |
41 | 1. Copyright and Related Rights. A Work made available under CC0 may be
42 | protected by copyright and related or neighboring rights ("Copyright and
43 | Related Rights"). Copyright and Related Rights include, but are not
44 | limited to, the following:
45 |
46 | i. the right to reproduce, adapt, distribute, perform, display,
47 | communicate, and translate a Work;
48 | ii. moral rights retained by the original author(s) and/or performer(s);
49 | iii. publicity and privacy rights pertaining to a person's image or
50 | likeness depicted in a Work;
51 | iv. rights protecting against unfair competition in regards to a Work,
52 | subject to the limitations in paragraph 4(a), below;
53 | v. rights protecting the extraction, dissemination, use and reuse of data
54 | in a Work;
55 | vi. database rights (such as those arising under Directive 96/9/EC of the
56 | European Parliament and of the Council of 11 March 1996 on the legal
57 | protection of databases, and under any national implementation
58 | thereof, including any amended or successor version of such
59 | directive); and
60 | vii. other similar, equivalent or corresponding rights throughout the
61 | world based on applicable law or treaty, and any national
62 | implementations thereof.
63 |
64 | 2. Waiver. To the greatest extent permitted by, but not in contravention
65 | of, applicable law, Affirmer hereby overtly, fully, permanently,
66 | irrevocably and unconditionally waives, abandons, and surrenders all of
67 | Affirmer's Copyright and Related Rights and associated claims and causes
68 | of action, whether now known or unknown (including existing as well as
69 | future claims and causes of action), in the Work (i) in all territories
70 | worldwide, (ii) for the maximum duration provided by applicable law or
71 | treaty (including future time extensions), (iii) in any current or future
72 | medium and for any number of copies, and (iv) for any purpose whatsoever,
73 | including without limitation commercial, advertising or promotional
74 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
75 | member of the public at large and to the detriment of Affirmer's heirs and
76 | successors, fully intending that such Waiver shall not be subject to
77 | revocation, rescission, cancellation, termination, or any other legal or
78 | equitable action to disrupt the quiet enjoyment of the Work by the public
79 | as contemplated by Affirmer's express Statement of Purpose.
80 |
81 | 3. Public License Fallback. Should any part of the Waiver for any reason
82 | be judged legally invalid or ineffective under applicable law, then the
83 | Waiver shall be preserved to the maximum extent permitted taking into
84 | account Affirmer's express Statement of Purpose. In addition, to the
85 | extent the Waiver is so judged Affirmer hereby grants to each affected
86 | person a royalty-free, non transferable, non sublicensable, non exclusive,
87 | irrevocable and unconditional license to exercise Affirmer's Copyright and
88 | Related Rights in the Work (i) in all territories worldwide, (ii) for the
89 | maximum duration provided by applicable law or treaty (including future
90 | time extensions), (iii) in any current or future medium and for any number
91 | of copies, and (iv) for any purpose whatsoever, including without
92 | limitation commercial, advertising or promotional purposes (the
93 | "License"). The License shall be deemed effective as of the date CC0 was
94 | applied by Affirmer to the Work. Should any part of the License for any
95 | reason be judged legally invalid or ineffective under applicable law, such
96 | partial invalidity or ineffectiveness shall not invalidate the remainder
97 | of the License, and in such case Affirmer hereby affirms that he or she
98 | will not (i) exercise any of his or her remaining Copyright and Related
99 | Rights in the Work or (ii) assert any associated claims and causes of
100 | action with respect to the Work, in either case contrary to Affirmer's
101 | express Statement of Purpose.
102 |
103 | 4. Limitations and Disclaimers.
104 |
105 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
106 | surrendered, licensed or otherwise affected by this document.
107 | b. Affirmer offers the Work as-is and makes no representations or
108 | warranties of any kind concerning the Work, express, implied,
109 | statutory or otherwise, including without limitation warranties of
110 | title, merchantability, fitness for a particular purpose, non
111 | infringement, or the absence of latent or other defects, accuracy, or
112 | the present or absence of errors, whether or not discoverable, all to
113 | the greatest extent permissible under applicable law.
114 | c. Affirmer disclaims responsibility for clearing rights of other persons
115 | that may apply to the Work or any use thereof, including without
116 | limitation any person's Copyright and Related Rights in the Work.
117 | Further, Affirmer disclaims responsibility for obtaining any necessary
118 | consents, permissions or other rights required for any use of the
119 | Work.
120 | d. Affirmer understands and acknowledges that Creative Commons is not a
121 | party to this document and has no duty or obligation with respect to
122 | this CC0 or use of the Work.
123 |
--------------------------------------------------------------------------------
/Pod/Classes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thurn/DTXcodeUtils/4082cfa5a6f985424904aef416d3a871b9da04b5/Pod/Classes/.gitkeep
--------------------------------------------------------------------------------
/Pod/Classes/DTXcodeUtils.h:
--------------------------------------------------------------------------------
1 | @class DVTSourceTextView;
2 | @class DVTTextStorage;
3 | @class IDEEditor;
4 | @class IDEEditorArea;
5 | @class IDESourceCodeDocument;
6 | @class IDEEditorContext;
7 | @class IDEWorkspaceWindowController;
8 |
9 | @interface DTXcodeUtils : NSObject
10 | + (NSWindow *)currentWindow;
11 | + (NSResponder *)currentWindowResponder;
12 | + (NSMenu *)mainMenu;
13 | + (IDEWorkspaceWindowController *)currentWorkspaceWindowController;
14 | + (IDEEditorArea *)currentEditorArea;
15 | + (IDEEditorContext *)currentEditorContext;
16 | + (IDEEditor *)currentEditor;
17 | + (IDESourceCodeDocument *)currentSourceCodeDocument;
18 | + (DVTSourceTextView *)currentSourceTextView;
19 | + (DVTTextStorage *)currentTextStorage;
20 | + (NSScrollView *)currentScrollView;
21 |
22 | + (NSMenuItem *)getMainMenuItemWithTitle:(NSString *)title;
23 | @end
24 |
--------------------------------------------------------------------------------
/Pod/Classes/DTXcodeUtils.m:
--------------------------------------------------------------------------------
1 | #import "DTXcodeUtils.h"
2 |
3 | #import "DTXcodeHeaders.h"
4 |
5 | @implementation DTXcodeUtils
6 |
7 | + (NSWindow *)currentWindow {
8 | return [[NSApplication sharedApplication] keyWindow];
9 | }
10 |
11 | + (NSResponder *)currentWindowResponder {
12 | return [[self currentWindow] firstResponder];
13 | }
14 |
15 | + (NSMenu *)mainMenu {
16 | return [NSApp mainMenu];
17 | }
18 |
19 | + (NSMenuItem *)getMainMenuItemWithTitle:(NSString *)title {
20 | return [[self mainMenu] itemWithTitle:title];
21 | }
22 |
23 | + (IDEWorkspaceWindowController *)currentWorkspaceWindowController {
24 | NSLog(@"getting window controller");
25 | NSWindowController *result = [self currentWindow].windowController;
26 | if ([result isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) {
27 | return (IDEWorkspaceWindowController *)result;
28 | }
29 | return nil;
30 | }
31 |
32 | + (IDEEditorArea *)currentEditorArea {
33 | return [self currentWorkspaceWindowController].editorArea;
34 | }
35 |
36 | + (IDEEditorContext *)currentEditorContext {
37 | return [self currentEditorArea].lastActiveEditorContext;
38 | }
39 |
40 | + (IDEEditor *)currentEditor {
41 | return [self currentEditorContext].editor;
42 | }
43 |
44 | + (IDESourceCodeDocument *)currentSourceCodeDocument {
45 | if ([[self currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) {
46 | return ((IDESourceCodeEditor *)[self currentEditor]).sourceCodeDocument;
47 | } else if ([[self currentEditor] isKindOfClass:
48 | NSClassFromString(@"IDESourceCodeComparisonEditor")]) {
49 | IDEEditorDocument *document =
50 | ((IDESourceCodeComparisonEditor *)[self currentEditor]).primaryDocument;
51 | if ([document isKindOfClass:NSClassFromString(@"IDESourceCodeDocument")]) {
52 | return (IDESourceCodeDocument *)document;
53 | }
54 | }
55 | return nil;
56 | }
57 |
58 | + (DVTSourceTextView *)currentSourceTextView {
59 | if ([[self currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) {
60 | return ((IDESourceCodeEditor *)[self currentEditor]).textView;
61 | } else if ([[self currentEditor] isKindOfClass:
62 | NSClassFromString(@"IDESourceCodeComparisonEditor")]) {
63 | return ((IDESourceCodeComparisonEditor *)[self currentEditor]).keyTextView;
64 | }
65 | return nil;
66 | }
67 |
68 | + (DVTTextStorage *)currentTextStorage {
69 | NSTextView *textView = [self currentSourceTextView];
70 | if ([textView.textStorage isKindOfClass:NSClassFromString(@"DVTTextStorage")]) {
71 | return (DVTTextStorage *)textView.textStorage;
72 | }
73 | return nil;
74 | }
75 |
76 | + (NSScrollView *)currentScrollView {
77 | NSView *view = [self currentSourceTextView];
78 | return [view enclosingScrollView];
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/Pod/XcodeHeaders/DTXcodeHeaders.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | @interface DVTTextStorage : NSTextStorage
4 | /** Whether to syntax highlight the current editor */
5 | @property(getter=isSyntaxColoringEnabled) BOOL syntaxColoringEnabled;
6 |
7 | /** Converts from a character number in the text to a line number */
8 | - (NSRange)lineRangeForCharacterRange:(NSRange)characterRange;
9 |
10 | /** Converts from a line number in the text to a character number */
11 | - (NSRange)characterRangeForLineRange:(NSRange)lineRange;
12 | @end
13 |
14 | @interface DVTCompletingTextView : NSTextView
15 | @end
16 |
17 | @interface DVTSourceTextView : DVTCompletingTextView
18 | @end
19 |
20 | @interface DVTViewController : NSViewController
21 | @end
22 |
23 | @interface IDEViewController : DVTViewController
24 | @end
25 |
26 | @class IDEEditorContext;
27 | @interface IDEEditorArea : IDEViewController
28 | @property(retain, nonatomic) IDEEditorContext *lastActiveEditorContext;
29 | @end
30 |
31 | @interface IDEEditor : IDEViewController
32 | @end
33 |
34 | @interface IDEEditorContext : IDEViewController
35 | @property(retain, nonatomic) IDEEditor *editor;
36 | @property(retain, nonatomic) IDEEditorArea *editorArea;
37 | @end
38 |
39 | @interface IDEEditorDocument : NSDocument
40 | @end
41 |
42 | @interface IDESourceCodeDocument : IDEEditorDocument
43 | @end
44 |
45 | @interface IDESourceCodeEditor : IDEEditor
46 | @property(readonly) IDESourceCodeDocument *sourceCodeDocument;
47 | @property(retain) DVTSourceTextView *textView;
48 | @end
49 |
50 | @interface IDEComparisonEditor : IDEEditor
51 | @property(retain) IDEEditorDocument *secondaryDocument;
52 | @property(retain) IDEEditorDocument *primaryDocument;
53 | @end
54 |
55 | @interface IDESourceCodeComparisonEditor : IDEComparisonEditor
56 | @property(readonly) DVTSourceTextView *keyTextView;
57 | @end
58 |
59 | @interface IDEWorkspaceWindowController : NSWindowController
60 | @property(readonly) IDEEditorArea *editorArea;
61 | @end
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DTXcodeUtils
2 |
3 | [](http://cocoadocs.org/docsets/DTXcodeUtils)
4 | [](http://cocoadocs.org/docsets/DTXcodeUtils)
5 | [](http://cocoadocs.org/docsets/DTXcodeUtils)
6 |
7 | ## Usage
8 |
9 | This is a collection of useful helper functions I am developing to make writing Xcode plugins easier. They
10 | provide access to various parts of Xcode internals by calling into Xcode's private APIs.
11 |
12 | An example of how to use the library is included in the Example directory. This shows how to make a simple
13 | plugin which toggles Xcode's syntax highlighting on or off.
14 |
15 | To run the example project, clone the repo, and run `pod install` from the Example directory. Open the resulting
16 | xcworkspace in Xcode and run the Example target. This should install the example plugin in the IDE. After
17 | restarting Xcode, you should get a "Toggle Highlighting" option in the Xcode Edit menu.
18 |
19 | ## Installation
20 |
21 | DTXcodeUtils is available through [CocoaPods](http://cocoapods.org). To install
22 | it, simply add the following line to your Podfile:
23 |
24 | pod "DTXcodeUtils"
25 |
26 | ## License
27 |
28 | DTXcodeUtils is available under the Creative Commons Zero license. See the LICENSE file for more info.
29 |
--------------------------------------------------------------------------------
/XcodeHeaders.h:
--------------------------------------------------------------------------------
1 | //
2 | // XcodeHeaders.h
3 | // Pods
4 | //
5 | // Created by Derek Thurn on 8/25/14.
6 | //
7 | //
8 |
9 | #ifndef Pods_XcodeHeaders_h
10 | #define Pods_XcodeHeaders_h
11 |
12 |
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------