Xcode Source Editor Extensionを試す

Qiitaに投稿した記事を手直ししたものです。

本記事は Xcode8 beta1 を対象に作成しています。

what's_new_dev_.png
WWDC2016にてXcode Source Editor Extension、Xcode Editor Extensionが発表されました。
Xcode用のApp Extensionが作れる、というものです。
Mac App Storeで配布もできるとのことでAlcatrazが不要になるかもしれませんね。

ここではXcode Source Editor Extensionを試してみます。

Xcode Source Editor Extensionとは?

名前の通りSource Editor部分を拡張するもので、現在できることは3つだけです。

・Add commands to the source editor = Source Editorへコマンドを追加
・Edit text = テキストの編集
・Change selections = 選択範囲の変更
Using and Extending the Xcode Source Editor 13:17頃より引用

残念ながら独自UIの表示・Xcodeメニューのカスタマイズなどはできないようになっています。
もっと広範を拡張したい場合はXcode Editor Extensionを作ることになるのかなと思います。

XcodeとExtensionの関係性を図にするとこんな感じです。

Xcodeとの関係

作ってみる

事前準備

macOS 10.11では事前に下記手順が必要です。

  • Xcode-betaを起動してadditional system componentをインストール
  • sudo /usr/libexec/xpccachectl を実行
  • macOSを再起動

プロジェクトの作成

まずはプロジェクトをCocoa Applicationテンプレートで作ります。

その後にFile > New > Target... または +ボタン(Add a target) から作成します。

以上でExtensionのSchemaを選択して実行(Choose an app to run:)でXcode8を選択すれば
Editorメニューに項目が追加されます。

Running状態になる前に操作するとうまく動きません。実行した後、一呼吸置きましょう。

生成されたファイルを見てみる

ターゲットを作成すると、下記のSwiftファイルが生成されます。

  • SourceEditorExtension.swift
  • SourceEditorCommand.swift
import Foundation
import XcodeKit

class SourceEditorExtension: NSObject, SourceEditorExtension {
	/*
    func extensionDidFinishLaunching() {
        // If your extension needs to do any work at launch, implement this optional method.
    }
	*/
    
    /*
    var commandDefinitions: [[XCSourceEditorCommandDefinitionKey: AnyObject]] {
        // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter.
        return []
    }
    */
}
import Foundation
import XcodeKit

class SourceEditorCommand: NSObject, XCSourceEditorCommand {
    
    func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: (NSError?) -> Void ) -> Void {
        // Implement your command here, invoking the completion handler when done. Pass it nil on success, and an NSError on failure.
        
        completionHandler(nil)
    }
    
}

さしあたり見るべきなのは4つだけで良さそうです。

  • extensionDidFinishLaunching

    起動時に呼ばれる。

  • commandDefinitions

    実行するコマンドの情報を定義する。
    info.plistに書いてある情報が使われるので定義しなくてもよい。

  • perform

    コマンドが実行されると呼ばれる。
    ここに処理を書く。

  • XCSourceEditorCommandInvocation

    これを操作する形でXcode Source Editorに干渉できるようです。
    詳細は定義にジャンプして覗くしかありません。

サンプル

XcodeSourceEditorExtension-Alignment - GitHub

選択範囲の代入文を整列する拡張です。
XcodeのEditorメニューにAlignmentが追加されます。

使い方

Xcodeでコードを選択状態にしてから Alignment を選択してください。

// before:
var hoge = "hoge"
var foo = "foo"
var awesome = ""
// after:
var hoge = "hoge"
var foo = "foo"
var awesome = ""

ショートカットキーの登録方法

開発者側によるデフォルト設定はできず、
Preference > KeyBindings からユーザーが設定するしかないようです。

メモ

Xcode-beta.app内に2つXcode Source Editor Extensionがありました。

名前 キー 説明
XCDocumenterExtension.appex ⌥⌘/ ドキュメントコメントを生成。中身はVVDocumenter† のようです。
IDECacheDeleteAppExtension.appex Derived Dataを消せる? Xcode Editor Extension のようです。

† VVDocumenterの作者@onevcatさんのツイートより。

参考

Xcode

公式の紹介ページ、Editor Extensionsの項目にてMac App Storeで配信できると書いてあります。

Release Note

New in Xcode 8.0 beta - IDE > Source Editor Extensions
Known Issues in Xcode 8.0 beta - IDE > Source Editor Extensions

Using and Extending the Xcode Source Editor

WWDC2016の関連セッション。
24:37からDemo、実際に作って試すところが見れます。