はじめに
macOS は Shift JIS のテキストファイルに今でも対応しています。ただし、Shift JIS は歴史的経緯から環境ごとに微妙に異なる文字を使っており、Windows の Shift JIS は CP932、macOS の Shift JIS は MacJapanese です。Windows はともかく macOS は UTF-8 を使うじゃん?と思うかもしれませんが、まず Windows の標準文字コードは Unicode (UTF-16) で、macOS は Unicode (UTF-8) 、どちらも Unicode なのは同じです。そして OS が使う標準文字コードとは関係なく、Windows は UTF-8 のファイルも扱えますし、macOS も Shift JIS のファイルを扱えます。ファイル内容の文字コードを何にするかはユーザーの自由です。
Shift JIS を扱えるのは互換性のために必要だからです。新たに作成するファイルでは使わないかもしれませんが、以前に作成されたファイルを扱うこともあります。互換性とはいつまでも古い文字コードを扱うことではなく、古いコードも扱えるということで、両方扱えるならば互換性を切り捨てる理由はありません。macOS になる以前の Mac は 当時の Windows 9x 系と同じように Shift JIS (MacJapanese) を使っていました。互換性、つまり古いファイルを扱うことを考えると macOS も Shift JIS に対応する必要があります。
macOS の「テキストエディット」アプリは文字コードを自動判定して、それが Shift JIS であると判明した場合は MacJapanese で開きます。macOS の文字コードの自動判定の仕様は不明ですが、おそらく現在の OS の言語設定も考慮されるでしょう。自動判定に完璧な方法は存在せず確率が高いものが選ばれるため、日本語以外に設定された状態では日本語専用の Shift JIS に判定される確率は低いはずです。ただし自動判定が使われるのは保存してないときだけです。テキストエディットは MacJapanese で保存されたファイルを開くと MacJapanse と解釈し、CP932 で保存されたファイルを開くと CP932 で開きます。しかしどの文字コードを使っているかを記録する方法が存在しないテキストファイルは Shift JIS が CP932 なのか MacJapanese なのか区別できないはずです。一体どういう仕組みを使って区別しているのでしょうか? というのがこの記事です。
答え
いきなり答えを書くと拡張属性 com.apple.TextEncoding
の値で区別しています。この一言で分かる人にはこれ以上説明は不要でしょう。ですが、macOS のテキストエディットアプリの仕様は少々注意が必要なものとなっています。
解説
まず、macOS のテキストエディットアプリは複数の Shift JIS に対応しています。そのことはファイルを開くまたは保存するときの(「オプションを表示」をクリックしたときの)「標準テキストのエンコーディング」でわかります。

ここに表示されいている「日本語 (Mac OS)」が MacJapanese(Mac 版の Shift JIS)で、「日本語 (Windows, DOS)」が CP932 (Windows 版の Shift JIS)で、「日本語 (Shift JIS)」がどちらでもない(おそらく)標準の Shift JIS です。他にも多くのエンコーディング(文字コード)に対応していることがわかります。
テキストファイルをエンコーディングを指定して開き、ファイルを保存すると拡張属性 com.apple.TextEncoding
が次のように設定されます。もしエンコーディングを指定しない場合は MacJapanese です。
- 日本語 (Mac OS) ・・・
x-mac-japanese;1
(MacJapanese) - 日本語 (Windows, DOS) ・・・
cp932;1056
(CP932) - 日本語 (Shift JIS) ・・・
shift_jis;2561
(Shift_JIS)
拡張属性 com.apple.TextEncoding
を保存するのは、テキストエディットの機能です。また参照するのもテキストエディット(やプレビュー)など、対応しているアプリに限られます。未検証ですが Spotlight にも影響があるかもしれません。Apple 製のアプリ以外に対応しているアプリがあるかは知りませんが、(少なくとも現在は)Visual Studio Code は対応していません。
この機能の注意点は、一度 com.apple.TextEncoding
が設定されてしまうとテキストエディットはそれを優先してしまうことです。つまり「標準テキストのエンコーディング」を指定してファイルを開いても、すでに com.apple.TextEncoding
が設定されている場合は、それを無視してしまうということです。なんでこんな直感的ではない仕様なんでしょうね。「標準テキストのエンコーディング」の標準とは com.apple.TextEncoding
が設定されていない場合のデフォルトという意味のようです。
この仕様がどういう問題を引き起こすかというと、例えば Windows から貰ったファイルをテキストエディットで編集すると MacJapanese として扱われるようになりますが、それを Visual Studio Code で開くと CP932 として扱うため、Visual Studio Code と テキストエディットやプレビューで異なる文字で表示されてしまうということです。例えば「① ② ③」という内容の Shift JIS のファイルを Visual Studio Code で作成し、テキストエディットで開くと「㈰ ㈪ ㈫」に文字化けします。テキストエディットで「日本語 (Windows, DOS)」を指定して開けば文字化けしませんが、もし com.apple.TextEncoding
が設定されていればずっと文字化けしたままです。拡張属性が有効なのは macOS だけの話なので、zip ファイルにまとめて Windows ユーザーとファイルのやり取りをしていれば、知らずに消えてしまうこともあるでしょう。
困ったことに、この拡張属性を GUI から確認または設定する方法は標準ではないようです。したがって拡張属性の存在やテキストエディットの仕様を知らない Mac ユーザーは、なぜか Shift JIS のファイルが文字化けする。それがずっと直らないと悩む羽目になります(実際に私が悩みました)。拡張属性の確認はターミナルから次のようなコマンドを入力します。
$ xattr file.txt
com.apple.quarantine
com.apple.lastuseddate#PS
com.apple.metadata:kMDLabel_ls4b2wqk4xmeznxrvit3gdtkdq
com.apple.TextEncoding
$ xattr -p com.apple.TextEncoding file.txt
cp932;1056
もし拡張属性を削除する場合には次のようにします。
$ xattr -d com.apple.TextEncoding file.txt
もし拡張属性を設定する場合には次のようにします。値にはシェルのメタ文字が含まれるためクォートが必要です。
$ xattr -w com.apple.TextEncoding "cp932;1056" file.txt
さいごに
macOS のテキストエディットはさまざまな文字コードに対応しており、Shift JIS にも対応しています。テキストエディットを使えば Windows ユーザーから貰った Shift JIS のファイルを文字化けせずに開けます。ただしデフォルトの Shift JIS が異なるため一部の文字が文字化けしてしまう可能性があります。文字コードに UTF-8 を使えばこのような問題は発生しません。したがってファイルは(Windows 側でも)UTF-8 を使うのが良いでしょう。UTF-8 に統一すれば一応文字化けせずに扱えるはずですが、BOM の問題やら NFC/NFD 問題が残っていたりと別の問題があったりします。いずれもそうする理由があるため、文字コードの問題は簡単に解決できるようなものではありません。