Home

Awesome

Sylvester 😼

<p align="center"> <a href="https://github.com/Carthage/Carthage" style="text-decoration:none" target="_blank"> <img alt="Carthage compatible" src ="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat"/> </a> <a href="https://cocoapods.org/pods/Sylvester" style="text-decoration:none" target="_blank"> <img alt="Pod Version" src ="https://img.shields.io/cocoapods/v/Sylvester.svg?style=flat"/> </a> <a href="https://travis-ci.org/chriszielinski/Sylvester" style="text-decoration:none" target="_blank"> <img src="https://travis-ci.org/chriszielinski/Sylvester.svg?branch=master"> </a> <a href="https://sonarcloud.io/dashboard?id=chriszielinski_Sylvester" style="text-decoration:none" target="_blank"> <img src="https://sonarcloud.io/api/project_badges/measure?project=chriszielinski_Sylvester&metric=alert_status"> </a> <a href="https://sonarcloud.io/component_measures?id=chriszielinski_Sylvester&metric=Coverage" style="text-decoration:none" target="_blank"> <img src="https://sonarcloud.io/api/project_badges/measure?project=chriszielinski_Sylvester&metric=coverage"> </a> <a href="https://codebeat.co/projects/github-com-chriszielinski-sylvester-master" style="text-decoration:none" target="_blank"> <img alt="codebeat badge" src="https://codebeat.co/badges/94e83fa7-6299-4c3c-a364-5c3aa958cf8e" /> </a> <a href="https://developer.apple.com/swift" style="text-decoration:none" target="_blank"> <img alt="Swift Version" src ="https://img.shields.io/badge/language-swift%204.2-brightgreen.svg"/> </a> <a href="https://github.com/chriszielinski/Sylvester/blob/master/LICENSE" style="text-decoration:none" target="_blank"> <img alt="GitHub license" src ="https://img.shields.io/badge/license-MIT-blue.svg"/> </a> <img alt="PRs Welcome" src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" /> <br> <br> <img src="https://github.com/chriszielinski/Sylvester/blob/master/.readme-assets/header.png?raw=true" alt="Header"> <br> <br> <b>A type-safe, XPC-available <a href="https://github.com/jpsim/SourceKitten"> SourceKitten</a> (SourceKit) interface with some sugar.</b> <br> </p>

Looking for...

Features

Requirements

Modules

The Sylvester framework has two build configurations that differ in their method of communicating with SourceKit:

πŸ“Œ Note: The XPC service itself cannot be sandboxed (due to inherent dependencies: xcrun, xcodebuild, sourcekitd), and requires an additional code signing step.

Installation

Sylvester is available for installation using Carthage or CocoaPods.

Using CocoaPods

🐞 Bug: Requires CocoaPods version >= 1.6.0 (Current pre-release, 1.6.0.rc.2)

πŸ“£ Important: The XPC service (and/or the SylvesterXPC module) is currently unavailable for CocoaPods installations.

pod "Sylvester"

Using Carthage

github "chriszielinski/Sylvester"

Dependencies

Sylvester/SylvesterXPC depends on the following frameworks/libraries, so ensure they are also embedded in the Embed Frameworks phase:

<p align="center"> <img src="https://github.com/chriszielinski/Sylvester/blob/master/.readme-assets/embed-frameworks.png?raw=true" alt="Embed Frameworks Phase"> </p>

Code Signing

If you decide to use the SylvesterXPC module, you will need to add a Run Script phase before embedding the SylvesterXPC.framework (i.e. before the Embed Frameworks phase). Ensure the shell launch path is /bin/sh (default). Then for Carthage installations, execute the code_sign_carthage.sh shell script in the repository's Scripts directory.

"$SRCROOT/Carthage/Checkouts/Sylvester/Scripts/code_sign_carthage.sh"
<p align="center"> <img src="https://github.com/chriszielinski/Sylvester/blob/master/.readme-assets/code-sign.png?raw=true" alt="Code Sign Phase"> </p>

For other installations, modify the script's paths as neccessary.

Supported Requests

RequestClass
Code CompletionSKCodeCompletion
Code Completion SessionSKCodeCompletionSession
Cursor InfoSKCursorInfo
Documentation InfoSKDocInfo
Editor OpenSKEditorOpen
Editor Extract Text From CommentSKEditorExtractTextFromComment
Convert Markup To XMLSKConvertMarkupToXML
Module InfoSKModule
Swift DocumentationSKSwiftDocs
Syntax MapSKSyntaxMap
Custom YAMLSKYAMLRequest

Other Fun Things

TypeMethod
XCRunSylvesterInterface.shared.xcRun(arguments:)
XcodeBuildSylvesterInterface.shared.xcodeBuild(arguments:currentDirectoryURL:)
Bash CommandSylvesterInterface.shared.executeBash(command:currentDirectoryURL:)
Launch SubprocessSylvesterInterface.shared.launch(subprocess:)

Subclassing

Most of the standard requests are concrete subclasses of beautiful generic classes. Fancy your own subclass? No problem, it might be possible.

SKSubstructure, SKEntity

Also known as SKBaseSubstructure (or SKBaseEntity), a common culprit.

πŸ“Œ Note: Subclassing SKBaseEntity uses similar syntax.

final class BetterSubstructureSubclass: SKBaseSubstructure, SKFinalSubclass {

    var iAmAnImportantProperty: String = "πŸšΆβ€β™‚οΈ"

    public override func decodeChildren(from container: DecodingContainer) throws -> [SKBaseSubstructure]? {
        return try decodeChildren(BetterSubstructureSubclass.self, from: container)
    }

    /// The default iterator for `SKChildren` does a pre-order (NLR) depth-first search (DFS) traversal; however, if you want something else, for instance:
    class FunctionSubstructureIterator<Substructure: BetterSubstructureSubclass>: SKPreOrderDFSIterator<Substructure> {

        override func next() -> Substructure? {
            guard let nextSubstructure = super.next()
                else { return nil }

            if nextSubstructure.isFunction {
                return nextSubstructure
            } else {
                return next()
            }
        }

    }

    override class func iteratorClass<Substructure: BetterSubstructureSubclass>() -> SKPreOrderDFSIterator<Substructure>.Type {
        return FunctionSubstructureIterator.self
    }

}

SKEditorOpen, SKSwiftDocs

An example of a SKSwiftDocs subclass utilizing the BetterSubstructureSubclass declared above:

πŸ“Œ Note: Subclassing SKEditorOpen uses identical syntax, except it inherits from SKGenericEditorOpen.

class BetterSwiftDocs: SKGenericSwiftDocs<BetterSubstructureSubclass> {

    var mySuperCoolProperty: String = "😎"

}

SKModule

An example of a SKModule subclass utilizing the BetterSwiftDocs and BetterSubstructureSubclass classes declared above:

class BetterModule: SKGenericModule<BetterSubstructureSubclass, BetterSwiftDocs> {}

Documentation

You can explore the docs here.

// ToDo:

Community

Contributors

Frameworks & Libraries

Sylvester depends on the wonderful contributions of the Swift community, namely:

License

Sylvester is available under the MIT license, see the LICENSE file for more information.