Xcode Source Editor Extension で複数のコマンドを定義する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Xcode Source Editor Extension

「Xcode Source Editor Extension」は、Xcode 8 から作れるようになった Xcode の Source Editor の機能拡張のことです。Xcode の Source Editor を拡張するような機能を、誰でも実装し提供することができます。

以下の記事では、Extension の作り方を紹介しました。

上記の記事では、自動生成されるクラスを使って1つのコマンドだけ作りましたが、1つの Extension に対して複数のコマンドを定義することができます。そこで、本記事では複数のコマンドを定義する方法を紹介します。

なお本記事の内容は、上記の記事で作成した Xcode プロジェクトをベースとします。本記事から読んだ方は、上記の記事からご一読いただければと思います。

コマンドの実装クラスの定義

まずはコマンドの実装クラスを新しく定義します。

「SampleExtension」グループの中でメニューを開き「New File...」を選択します。

xcode-see-multi-command-01

「macOS」の中の「CocoaClass」を選びます。

xcode-see-multi-command-02

クラス名は SecondCommand とし、NSObject のサブクラスにします。

xcode-see-multi-command-03

Swift ファイルは「SampleExtension」ディレクトリの中に作成します。

作成後は、次のような実装コードになっています。

import Cocoa

class SecondCommand: NSObject {

}

これを、次のソースコードに書き換えます。

import Foundation
import XcodeKit

class SecondCommand: NSObject, XCSourceEditorCommand {
    
    func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void {
        let textBuffer = invocation.buffer
        
        let lines = textBuffer.lines
        let selections = textBuffer.selections
        
        guard let selection = selections.firstObject as? XCSourceTextRange else {
            completionHandler(NSError(domain: "SampleExtension", code: 401, userInfo: ["reason": "text not selected"]))
            return
        }
        
        let line = selection.end.line
        let end = selection.end.column
        
        let indentSpace = String(repeating: " ", count: end)
        lines.insert("\(indentSpace)let message = \"Good Morning!\"", at: line)
        
        completionHandler(nil)
    }
    
}

let message = "Good Morning!" というコードを追加するだけのシンプルなコマンドです。

Info.plist の編集

Info.plist は次のように構成されています。

xcode-see-multi-command-04

XCSourceEditorCommandDefinitions の中に、提供したいコマンドを記述します。コマンドの定義に必要な項目は次の通りです。

項目 説明
XCSourceEditorCommandClassName クラス名 $(PRODUCT_MODULE_NAME).SecondCommand
XCSourceEditorCommandIdentifier ID $(PRODUCT_BUNDLE_IDENTIFIER).SecondCommand
XCSourceEditorCommandName コマンドの表示名 2つ目のコマンド

XCSourceEditorCommandClassNameXCSourceEditorCommandIdentifier はクラス名に従うようにしますが、XCSourceEditorCommandName は自由に決めることができます。ここでは分かりやすく日本語表記にしてみます。

xcode-see-multi-command-05

以上で、コマンドの実装は終わりです。

デバッグ

デバッグしてみましょう。メニューの「Editor」の「SampleExtension」の中に「2つ目のコマンド」が追加されているはずです。

xcode-see-multi-command-06

実行すると、コードが追加されます。

xcode-see-multi-command-07

まとめ

1つの Extension の中に何個もコマンドを作ることができるので、ソースコードを編集する機能をたくさん提供したり、コマンドを用途によって分けたりすることができます。

参考