vim-jp / issues

有志で既知のバグや要望を検討・管理し、オフィシャルへの還元をしていきます。
https://vim-jp.org/
342 stars 11 forks source link

diffopt=internalがあるとFilterWritePreが発火しない #1206

Closed rapan931 closed 5 years ago

rapan931 commented 5 years ago

質問・報告の内容

適当なバッファーを二つ並べてwindo diffthis実施時に FilterWritePreが発火していないように見えます。

再現手順

vim.exe -Nu NONE -c "execute \"autocmd FilterWritePre * echo 'hogehoge'\" | put=&diffexpr | vnew | put=&diffopt | windo diffthis"

上記を実行してもechoされませんでした。

Vimのバージョン

VIM - Vi IMproved 8.1 (2018 May 18, compiled Nov 18 2018 23:03:12) MS-Windows 64 ビット コンソール 版 適用済パッチ: 1-536

OSの種類/ディストリ/バージョン

使用している or 関係していそうなプラグイン

特にありません。

その他

diffopt=internalがあると、FilterWritePreが発火しないようです。以下はechoされました。

vim.exe -Nu NONE -c "set diffopt=filler | execute \"autocmd FilterWritePre * echo 'hogehoge'\" | put=&diffexpr | vnew | put=&diffexpr |

FilterWritePreがいまいち理解できていないため、もしかしたら仕様通りなのかもしれません。。 すみませんがご確認宜しくお願いします。

h-east commented 5 years ago

@rapan931 Issue登録ありがとうございます。

内部diff時('diffopt'internalが含まれている)にFilterWritePreイベントが発火しないのは仕様ですね。 以下は :h FilterWritePre の日本語訳です。

                                                        FilterWritePre
FilterWritePre                  フィルタコマンド用のファイルを書き込んだり、差
                                分表示用のファイルを作る前。
                                Vimはフィルタコマンドの出力である一時ファイル
                                の名前ではなく、現在のバッファの名前に対してパ
                                ターンをチェックする。
                                'shelltemp' がオフのときは発生しない。

diffモードに関係するのは「差分表示用のファイルを作る前。」の記述ですが、内部diffの場合は言葉通りVimの内部でdiffの処理をおこなうので、ファイルを作成する必要はありません。

Vimのソースコードで言うと、buf_write()の最後の引数がTRUEの時にこのイベントが発火する可能性があります。 buf_write()の最後の引数をTRUEで呼び出しているのは以下の3関数です。

do_filter()
diff_write()
ex_diffpatch()

関係するのは diff_write() で、この関数を呼んでいるのが diff_try_update() です。 そして、diff_try_update() は冒頭で外部diff以外の場合はreturnするという判定があります。

    // Check external diff is actually working.
    if (!dio->dio_internal && check_external_diff(dio) == FAIL)
        goto theend;

ですので、内部diffの場合にFilterWritePreイベントが発火しないのは仕様だとhelpからもソースコードからも受け取れます。

rapan931 commented 5 years ago

@h-east 早速の回答ありがとうございます。

内部diffが「差分表示用のファイルを作る前。」という箇所に該当するのかな?でもよく分からない。。

という状況だったのですが、教えたいだき理解できました。ありがとうごさいます!

関連するコードについても提示していただきましたし、折角なのでVimのソースも見てみます。

ありがとうございました!