Help us understand the problem. What is going on with this article?

IMEを使う(macOS編)

More than 3 years have passed since last update.

はじめに

AppleのIME APIはドキュメントを読んだだけでは実装できないと思うので、わりと有用な記事になるかもしれません。

NSTextInputClient

Objective-Cだと10.5以降、Swiftだと10.10以降に対応という楽しいProtocolです。
他のIME APIと同様に、自前のTextViewを作るときくらいにしか使われません。
https://developer.apple.com/reference/appkit/nstextinputclient?language=objc)

大まかな実装の手順は以下のとおり。

  1. NSView<NSTextInputClient>を継承したViewを作る
  2. このView上に編集対象のテキストを表示可能にする
  3. NSTextInputClientの関数を実装する

これで、IMEを正しく扱うことができます。
WindowsのTSFと比較すると以下の機能には対応していません。

  • 複数の文字列選択
  • アプリケーション側からの再変換要求

ドキュメントに書かれていないこと

ドキュメントに幾度となく現れるmarked textとselected textですが、ドキュメントではそれらがどういう値を返すべきかという点については記述されていません。
なので初見殺しであろうこれらについて、実装した際の挙動から推測される定義をまとめておきます。

marked textとは何か

  • 未確定文字列があるとき
    • 未確定文字列の範囲
  • 未確定文字列がないとき
    • なし: {NSNotFound, 0}

selected textとは何か

  • 未確定文字列があるとき
    • 未確定文字列中のsetMarkedTextで渡された範囲
  • 未確定文字列がないとき
    • 選択中の文字列の範囲

実装メモ

基本

以下の関数は素直に実装しましょう。

  • hasMarkedText
    • 未確定文字列の有無
  • markedRange
    • 未確定文字列の範囲
  • selectedRange
    • 選択文字列の範囲
  • setMarkedText
    • 未確定文字列の挿入
  • unmarkText
    • 未確定文字列の解除
  • validAttributesForMarkedText
    • 表示可能な装飾
  • attributedSubstringForProposedRange
    • 指定範囲の文字列
  • insertText
    • 文字列の挿入
  • characterIndexForPoint
    • ディスプレイ上の座標に対応する文字のインデックス
  • firstRectForCharacterRange
    • 指定された範囲の文字列の最前方の矩形
  • doCommandBySelector
    • 適宜処理する

縦書きのために

縦書きのために必要なことは、drawsVerticallyForCharacterAtIndex(オプションの関数)でYESを返すことです。
そのものズバリで簡単ですね。

再変換のために

文字列の再変換のために必要なことは、attributedString(オプションの関数)を常に返すことです。
つまりNSAttributedStringという文字列長に比例した大きさのオブジェクトを返さなければいけません。
NSAttributedStringが世界最高の文字列クラスなら問題ないのですが、そんなことはないので実装には注意しましょう。
もちろんNSAttributedStringを使うならば何も問題はありません。
(TATEditorのデフォルトではIME側に見せる文字列の範囲をある程度狭めて返すようにしてます)

おわりに

素晴らしきAppleのドキュメントの充実っぷりを味わうことができたかと思います。

さて、明日はIME APIのGTK+編です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした