2019/11/17

Disable Text Replacement on Safari in Mojave

iOS で文字入力をする際、入力が億劫な定型文とかを登録してみる。
  • General > Keyboard > Text Replacement 
で追加できます。

そこそこ快適になったと思ったら、iCloud 経由で自動的に Mac にも sync される様子。
基本的には無害なのですが、一度 GitHub の sha1 の末尾が置換対象と認識されて誤爆しかけた。ので無効化させる事に。
以下、 iOS では Text Replacement を有効にしつつ、Mac では無効化したログ。意外と大冒険だった。


環境

  • OS: macOS Mojave 10.14.6
  • Saferi: Version 13.0.3 (14608.3.10.10.1)
  • iOS: 12.3.2 and 13.2.2


結論から言うと

以下のコマンドを実行すると Mac の Text Replacement 設定を全て削除できます。
  • $ echo 'delete from ZTEXTREPLACEMENTENTRY;' | sqlite3 ~/Library/KeyboardServices/TextReplacements.db
  • $ defaults delete -g NSUserDictionaryReplacementItems
これで macOS では Text Replacement が発生しなくなります。
あくまで delete なので、iOS 側で設定を追加すると、同期された設定を再度削除する必要があります。


設定が存在しないか探す

iCloud の設定等、怪しい部分を探すも、それらしきものを発見できず。


$ defaults write -g WebAutomaticTextReplacementEnabled -bool false

ググると同じ考えの人はいて、
  • $ defaults write -g WebAutomaticTextReplacementEnabled -bool false
すると良い、とのことで実行。しかし変化無し。

きちんと設定されているか分からないのでまずは設定を表示させる。
man defaults すると read があるので実行してみる。
  • $ defaults read -g WebAutomaticTextReplacementEnabled
    • => 0
0なので一応 false になってる、という事なのだろうか。
delete もあるので実行する。
  • $ defaults delete -g WebAutomaticTextReplacementEnabled
  • $ defaults read -g WebAutomaticTextReplacementEnabled
    • => The domain/default pair of (kCFPreferencesAnyApplication, WebAutomaticTextReplacementEnabled) does not exist
delete した場合は 0 すら返らないので、設定できていたことになる。
しかし効果は表れなかったので、この方法では無理そう。


$ defaults find TextReplacement

defaults には find 機能もあるようだったので、
  • $ defaults find TextReplacement
とすると大量の設定が返ってくる。

defaults は多分 NSUserDefauts を macOS 側からいじる用のコマンドだと思われる。
Application 毎に設定があるし、Application 側で値を変更したら defaults で見られる情報に変化があった。
具体的には 'com.apple.iWork.Keynote' の 'TSWPAutomaticTextReplacement' の値とか。
Keynote で Text Replacement を disable にすると 'TSWPAutomaticTextReplacement' の値が 0 になる。

ちなみに -g は global option らしい。
Safari だけに効くよう、以下のように domain を指定して設定してみる。
  • $ defaults write com.apple.Safari TSWPAutomaticTextReplacement -bool false
しかし無効化できず。うーん。


$ defaults write -g WebAutomaticTextReplacementEnabled -bool true

逆に 0 でなく 1 を設定してみる。そうすると 
  • Menu bar(Safari) > Edit > Substitutions
が select できるようになる。
その中の 'Text Replacement' を disable にすると置換が止まった。
後はこれを defaults のどこに書くのか調べると良さそう。

と、思ったがそうは問屋が卸さなかった。defaults を使っても設定が見付けられない。
その上、 Saferi で 新規 Window を開くと 'Text Replacement' が Enabled な Window が増える。
あと、mac を reboot したら Text Replacement がまた有効になる。
どこかに設定があるからそれに辿りつけば良いんだけれど、対症療法ではどうも分が悪そう。


$ defaults write -g NSUserDictionaryReplacementItems <dictionary>

設定の場所を特定するためにわざと 'hoge' とかを TextReplacement に追加する。
そして
  • $ defaults find hoge
で調べると、NSUserDictionaryReplacementItems という Dictionary に格納されている。

NSUserDictionaryReplacementItems をググると少ないが記事はある
それを辿ると ~/Library/Preferences/.GlobalPreferences.plist というファイルの存在が示唆されている。
  • $ ls ~/Library/Preferences/.GlobalPreferences.plist
すると一応存在している。
  • $ open -a XCode.app ~/Library/Preferences/.GlobalPreferences.plist
内容は defaults read -g と同じっぽい。のでこれをいじっても defaults とやっている事は変わらない筈。

またググって引っかかった記事によれば
  • NSUserReplacementItems は 10.8 より前のバージョンで使われている
  • NSUserDictionaryReplacementItems は 10.9 で使われてる
とのことで。NSUserDictionaryReplacementItems をいじることにする。

元の値を一度取り出して
  • $ defaults read -g NSUserDictionaryReplacementItems 
    • => '( { on = 1; replace = hoge; with = "hogefugapiyo"; } )'
on を 0 にして、書き込む
  • $ defaults write -g NSUserDictionaryReplacementItems '( { on = 0; replace = hoge; with = "hogefugapiyo"; } )'
しかし Text Replacement は発生してしまう。
が、 Safari を起動すると、Text Replacement が発生しなくなった。ということでコレで良さそうだ。
その後、 macOS を再起動しても on flag は 0 のままだった。これで解決かな。


復活する NSUserDictionaryReplacementItems

解決かと思ったがそうでも無かった。しばらくすると on flag が 1 になっていた。
iCloud から sync した時に 1 になるなら理解できるが、特に編集せずとも 1 になる時がある。

ググると DB に格納されている、という記事が。
  • $ ls /Library/Dictionaries/CoreDataUbiquitySupport/atton~*/UserDictionary/local/store/UserDictionary.db
確かにある。sqlite3 で中身を覗いてみるとデータが無い。
というか ls -l したら 0B だった。のでここでは無い。


ちなみに、 on flag が 1 になる再現条件の一つは
  • System Preferences > Keyboard > Text を見る
でした。とりあえず確認に使えるので再現方法が1つ見付かっただけありがたい。


echo 'delete from ZTEXTREPLACEMENTENTRY;' | sqlite3 ~/Library/KeyboardServices/TextReplacements.db

Dictionary の save 先が無いかなー、とかググっていると ~/Library/Spelling に text edit の auto correction の情報がある、という記事にぶつかる。

~/Library をいろいろ見ると
  • $ ls ~/Library/KeyboardServices/TextReplacements.db
という怪しい物体を発見。早速中を見る。
  • $  file KeyboardServices/TextReplacements.db
    • => KeyboardServices/TextReplacements.db: SQLite 3.x database, last written using SQLite version 3016000
  • $ sqlite3 ~/Library/KeyboardServices/TextReplacements.db
    • sqlite> .schema
      • CREATE TABLE ZTEXTREPLACEMENTENTRY
      • CREATE TABLE ZTRCLOUDKITSYNCSTATE 
      • CREATE INDEX ...
      • CREATE TABLE Z_PRIMARYKEY
      • CREATE TABLE Z_METADATA
      • CREATE TABLE Z_MODELCACHE
    • sqlite> select * from ZTEXTREPLACEMENTENTRY limit 1;
      • 4|1|1|0|0|582166527.750349|三度寝|さんどね|C561DE44-D3D9-4F37-95E6-5916FF62C390|bplist00=>X$versionX$objectsY$archiverT$top
システム設定が参照しているかはともかく、コイツが Text Replacement のデータを保存しているのは間違いなさそう。

とりあえずバックアップを取って消してみる。
  • sqlite> delete from ZTEXTREPLACEMENTENTRY;
  • sqlite> select * from ZTEXTREPLACEMENTENTRY;
    • 消えてるので record は無い
System Preferences > Keyboard > Text を開くと見事に消えている。
ので NSUserDictionaryReplacementItems が復活する事も無さそう。
ということで defaults で NSUserDictionaryReplacementItems を消す。
  • $ defaults delete -g NSUserDictionaryReplacementItems
これにて一段落。これらを調べた結果が最初に書いた例の2行です。



余談: WebKit の shallow clone とか

ソース読むかー、ということで WebKit を落とそうとするも時間がかかりすぎる。
  • $ git clone --depth 1 git://git.webkit.org/WebKit.git WebKit
何かないかと git grep -i replacementした結果
  • NSUserDictionaryReplacementItems
  • ContextMenuItemTagTextReplacement
  • WebMenuItemTagTextReplacement
  • kWKContextMenuItemTagTextReplacement
等があって更に混乱した。それと対応してなのか
  • ContextMenuItemTagSmartCopyPaste
  • WebMenuItemTagSmartCopyPaste
  • kWKContextMenuItemTagSmartCopyPaste
等もあり迷宮じみてる感じ。ちなみに depth 1 でも 4.5GB というトンデモサイズです。


参考

1 件のコメント:

  1. THANK YOU SO MUCH FOR SHARING THIS!
    This is literally the only working solution on the web.

    返信削除