vim-jp / issues

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

diff 後 matchadd() しても思うようにハイライトされない #731

Open rickhowe opened 9 years ago

rickhowe commented 9 years ago

最近の 7.4.725 で気付いたことです。 例えば aaa xxx aaa xxx aaa aaa yyy aaa yyy aaa の 2 つのテキストを diff すると、中央の xxx aaa xxx と yyy aaa yyy が DiffText (gui=bold guibg=Red) でハイライトされますが、この後、matchadd("MatchParen", "aaa") を行うと、どの aaa も MatchParen で同じようにハイライトされていました。ところが、7.4.725 では、DiffText でハイライトされた中央の aaa はボールドのまま残ります。 入手できるバイナリで調べてみたら、7.4.648 以降、7.4.688 以前で動きが変わったようです。 該当しそうなパッチとなると、 7.4.682 search and match highlighting replace cursorline highlighting あたりなのでしょうか。 この動作変更は仕様なのでしょうか?

mattn commented 9 years ago

http://ftp.vim.org/vim/patches/7.4/7.4.682

この修正ですね。

mattn commented 9 years ago

失礼、ボタン間違えました。

mattn commented 9 years ago

私の所なとこんな感じです。

キャプチャ見せて貰ってよろしいですか?

h-east commented 9 years ago

@mattn 真ん中のaaaがボールドになっているのが「前と違うぜ!」とのことなのでmattnさんのキャプチャでも再現しているということになります。

mattn commented 9 years ago

再現というか、matchadd で 11122233344455 のうち 22233344 を(※1)、さらに matchadd で 333 だけを(※2)ハイライトした場合に、僕は 333 が ※1 と※2 の合成になるべきだと思っているのですが、どうでしょうか?

h-east commented 9 years ago

ということは7.4.682で挙動が変わったけど今の挙動が正しいので報告の件は「仕様です」ということですね。 確かにそうかも。任せました!

rickhowe commented 9 years ago

自ら matchadd() していれば、どちらかをクリアすればよいのですが、diff の場合はどうにもできないので困っています。

h-east commented 9 years ago

そうそう、diffモードの時って:syntax offが聞かないんですよね。これを対応するの難しいんでしょうか?

rickhowe commented 9 years ago

こんな感じです。

7.4.648 7 4 648

7.4.725 7 4 725

mattn commented 9 years ago

MatchParen で bold を打ち消す standout を設定すれば上書き出来ます。

hi MatchParen term=reverse cterm=standout ctermbg=3 guibg=DarkCyan
mattn commented 9 years ago

MatchParen が fg を設定していないので、この動作は個人的には期待動作です。

rickhowe commented 9 years ago

MatchParen は説明のための一例です。DiffText がどのようなものでも、以前のように matchadd のハイライトで完全に上書きできないでしょうか。

mattn commented 9 years ago

DiffText だけ特例処置を入れて fg 属性をコピーしないという意味でしょうか?

mattn commented 9 years ago

それなりの説明をしないと変更させては貰えませんので、出来ればどの様に困っているのかを教えて貰えませんか?教えて貰えると助かります。

rickhowe commented 9 years ago

diffchar.vim (http://www.vim.org/scripts/script.php?script_id=4932) というプラグインを投稿しているのですが、次のようになってしまいました。 まず行全体を DiffChange で matchadd() し、その後、実際の diff の部分を DiffText や DiffAdd で matchadd() していますが、diff のハイライトが version によって上書きできなくなってしまい困っています。

7.4.648 7 4 648

7.4.725 7 4 725

mattn commented 9 years ago

diff のハイライトが version によって上書きできなくなってしまい

この部分ですが、上書きしようとしているのはどの部分で、どの様にでしょうか?

rickhowe commented 9 years ago

この例ですと、DiffChange で行全体を matchadd() していますが、" fox jumped over the " と DiffAdd (LightBlue) で matchadd() した "brown" の部分が bold のまま残ってしまいます。DiffText (Red) でも matchadd() していますが、diff と同じ部分ですので上書きできなくても問題ないです。

mattn commented 9 years ago

hihight の結果を教えて貰えますか?

redir > highlight.log
silent highlight
redir END

で取れます。おそらくですが、DiffAdd の gui もしくは guifgが指定されていないのだと思います。

rickhowe commented 9 years ago

diff を含めてハイライトはデフォルトのままです。各ユーザーがスキームをカスタマイズしている場合が多いので、プラグインでこれを変えてしまうのはまずいです。 要はどのハイライトでも、これまでできていたように diff ハイライトを上書きしたのですが、7.4.682 のパッチではこの上書きができていたことが不具合と認識されたのでしょうか、それとも結果的にたまたまそうなってしまったのでしょうか。

rickhowe commented 9 years ago

再現というか、matchadd で 11122233344455 のうち 22233344 を(※1)、さらに matchadd で 333 だけを(※2)ハイライトした場合に、僕は 333 が ※1 と※2 の合成になるべきだと思っているのですが、どうでしょうか?

についてですが、matchadd() の priority 指定で上書きされる仕様なので、合成されてはまずいです。

mattn commented 9 years ago
highlight MyGroup1 ctermbg=green guibg=green ctermfg=yellow
highlight MyGroup2 ctermfg=red guifg=red
call matchadd("MyGroup1", "FOOBARBAZ")
call matchadd("MyGroup2", "BAR")

" FOOBARBAZ

これの動作を見る限り、matchadd 同士だと上書き動作になっている様です。 問題は行色属性の場合だけの様ですが、いかがでしょうか?

rickhowe commented 9 years ago

7.4.682 以降でも matchadd() 同志の問題はありません。 問題は、matchadd() は合成する機能がないにもかかわらず、diff でハイライトされた部分全体が matchadd() と合成されてしまうようになったことだと思います。 行色属性とは gui のことでしょうか。試してみると guifg も guibg も diff ハイライトと合成されてしまいます。

mattn commented 9 years ago

行色属性は、cursorline や DiffChanged 等だけ特例として内部で使われている物で、本来 vim のハイライトは1行丸ごと塗りつぶす機能は無いのですが、これらだけそれを実現する為に特例処置が入っています。7.4.682 はこの行色属性と match に限らない表側の色を合成する修正ですが、行色属性の前景属性を抜いた値で合成すればうまく修正されるかもしれません。

rickhowe commented 9 years ago

内部のメカニズムは不案内なのでよくわかりませんが、 gui も guifg も guibg も合成されてしまいますので 前景以外の属性も関係あるのでしょうか。 それはともかく、修正いただければ助かります。

mattn commented 9 years ago

合成されるのが正しいと思う人もいるかもしれませんので、修正するかどうかは、一度 vim-dev で相談して決めたいと思います。

mattn commented 9 years ago

説明に画像をお借りしたいのですが良いでしょうか?

rickhowe commented 9 years ago

合成されるのが正しいと思う人もいるかもしれませんので、

の真意は不明ですが、まずは matchadd() の上書き仕様変更の是非を確認していただきたいと思います。MatchParen の例でいかがでしょうか。 次に diff は例外ということになれば、その実害ととして diffchar.vim の例を使ってください。ある程度ダウンロードされているようですのでそのうちユーザーからクレームがあると思いますが、現状ではワークアラウンドもありません。

mattn commented 9 years ago

えと、画像は使って良いでしょうか?

mattn commented 9 years ago

合成されるのが正しいと思う人もいるかもしれませんので、 の真意は不明ですが

くどい返しにご立腹かと思います。Bramの判断にもよりますが、皆の反応次第で修正方法が異なってくるので、くどくなって申し訳ないのですが確認させて頂いてます。 上記のaaaがboldになっている件の何が問題なのかにより

など色んな修正案があり、またZBryceさんからお聞きした1意見だけで修正方針を決定する内容でもないと思っています。「修正したよ」とパッチを投げても「何がイケてないのか」を説明しないといけないですからね。

rickhowe commented 9 years ago

誤解を与えてしまったら申し訳ありません。立腹してませんのでご安心ください。 画像は使えるのでしたらお使いください。 問題は matchadd() は合成する仕様でなく、上書きする仕様なのになぜ dIff だけ例外になるのかということです。しかもパッチレベルで急に仕様を変更することで実害が出ていると思いますが、これでは説得力に欠けるでしょうか?

mattn commented 9 years ago

元々、cursorline 上にハイライトを行うと、そこが欠けるという不具合がありました。 それを直したのが 7.4.682 なのです。ですので、「合成されていなかった」が故障内容で「合成される様になった」という修正内容になります。個人的には仕様変更ではなく「動かなかった物が動くようになった」という意識です。

ですが、7.4.682 は内部が使っている行色属性を使っている為、cursorline の問題は直りましたが、DiffChanged にも影響します。つまり、上記で仰られている内容は DiffChanged だけでなく CursorLine でも確認出来るはずです。これが今回の issue の内容と理解しています。

これに対して vim-dev の皆が

のどちらを言うのか次第だと思っています。ですのでまずは「どう思います?」という所から始める予定です。

mattn commented 9 years ago

https://groups.google.com/forum/#!topic/vim_dev/BOAkHUFophc

rickhowe commented 9 years ago

CurorLine の場合は統合したほうが良いと判断されたのですね。diff ではこれと同じ基準を適用するのが正しいかどうかでぜひご判断ください。私個人としては逆に実害が出ていますので、実装上の都合だけから単に判断されないようによろしくお願いします。

mattn commented 9 years ago

何度もすみません。その害と仰られる部分が聞きたいのですが、何が害なんでしょうか?上記の例の真ん中のaaaで言えば、DiffTextの一部と表現出来る方法があるとも取れるのですが。

rickhowe commented 9 years ago

了解しました。上記の diffchar.vim の画像で、DiffChange と DIffAdd でもボールドが残ってしまう部分です。別の例ですが、diff 部分が多いと、そこに残ったボールドとそれ以外の部分に何らかの違いがあるように見えてしまいます。ユーザーから見ると、vim を更新したことが理由であるとは納得されないように思うのですが、どうでしょうか。

7.4.648 と 7.4.725 での diff 直後 before

7.4.648 での diffchar 抽出 after648

7.4.725 での diffchar 抽出 after725

mattn commented 9 years ago

こちらの画像もお借りして追記します。ありがとうございました。

rickhowe commented 9 years ago

よろしくお願いします。この例はデフォルトのままのハイライトで bold ですが、違いを目立たせるように bold, underline, italic を組み合わせている場合も多くあるようで、その場合はそれも残ってしまいます。

rickhowe commented 9 years ago

一応その画像も載せておきます。

before2

after6482

after7252

rickhowe commented 9 years ago

私1人だけでは何なので、vim_use で関心のある人の意見を聞いています。

h-east commented 9 years ago

@ZBryce ++

オフトピックになりますが1点だけ。

from this issue's comment

しかもパッチレベルで急に仕様を変更すること

from your vim_use post

I am a bit surprised at such a sudden change of the behavior anyway

これらはVimに関しては通常営業になります。(それが良いか悪いかの議論は別として) パッチレベルですごく変化がおこります。

以上、事実をお伝えしました。

rickhowe commented 9 years ago

この回避策を考えているのですが、不明な動作がありましたので報告いたします。 これは vgim (7.4.729) の話です。colo default の状態です。

一番最初に取り上げた例で diff 後に matchadd("Search", "aaa") を行うと、中央の aaa は DiffText のボールドが残り、両側の aaa のハイライトとは異なります。これが7.4.682 での変更でした。 1

(1) そこでこのボールドを上書きできないかと、hi serach font= で guifont オプションのフォントを指定してみたら、ボールドは消えてすべての aaa は同じハイライトになりました。 2

(2) 次にボールド以外を試そうとして hi DiffText gui=italic にしたら、中央の aaa になぜかアンダーラインが付きました。 3

(1) これは意図された動きなのでしょうか? (2) アンダーラインはどこにも指定されていないので不具合のようですが、いかがでしょうか?

mattn commented 9 years ago

何度かやってるのですが再現しませんね。

FixedSys で試しました。

rickhowe commented 9 years ago

Search がデフォルトのままですとこのようになりますが、font 属性は消えてないでしょうか? 私の使っている 7.4.729 では FixedSys でも同じようにアンダーラインが付きます。 gvim -u NONE で試してみました。 4

ynkdir commented 9 years ago

再現できました vim-7.4.729 64bit on windows10tp

> gvim -u NONE -N
:e a.txt
:diffsplit b.txt
:call matchadd("Search", "aaa")
:hi Search font=FixedSys
:hi DiffText gui=italic
mattn commented 9 years ago

僕も再現出来ました。 デフォルトでは guifont が設定されてなかったので自分で設定したのと、h14:cSHIFTJIS まで足さないと再現しなかったです。

rickhowe commented 9 years ago

diff 後の DiffText ハイライト部分を上書きする方法を模索しています。guifg、guibg は色を明示的に指定すればよいのですが、gui は迷っています。bold は font を指定することで消えるようですが、italic はこのような状態であり、underline は font を指定しても消えません。undercurl、reserve も同様に消えず、standout は bold が消えます。何が仕様で何が不具合なのか、確認させていただければと思います。 cterm については font という概念がないですし、どうしたものかと悩んでいます。

rickhowe commented 9 years ago

いろいろと模索しましたが、色やフォント属性を指定して上書きするには限界がありそうなので、やめました。私の場合、DiffText の部分だけが問題ですので、まず highlight オプションを "Tn" に設定し、同じ部分を DiffText で matchadd することで見かけ上同じようにし、上書きできるようにしました。highlight オプションを変更すると、その都度 redraw されるので、ちらつくのがやや気になりますが、何とかなりました。プラグインも更新しました。いろいろとありがとうございました。

ynkdir commented 9 years ago

フォント指定 + italic で下線が付く件

フォントの斜体描画を下線で疑似表現してるらしいです。

このへん。

gui.c:gui_outstr_nowrap()
2376 #if defined(FEAT_GUI_GTK)
2377     /* If there's no italic font, then fake it.
2378      * For GTK2, we don't need a different font for italic style. */
2379     if (hl_mask_todo & HL_ITALIC)
2380         draw_flags |= DRAW_ITALIC;
2381
2382     /* Do we underline the text? */
2383     if (hl_mask_todo & HL_UNDERLINE)
2384         draw_flags |= DRAW_UNDERL;
2385 #else
2386     /* Do we underline the text? */
2387     if ((hl_mask_todo & HL_UNDERLINE)
2388 # ifndef MSWIN16_FASTTEXT
2389             || (hl_mask_todo & HL_ITALIC)
2390 # endif
2391        )
2392         draw_flags |= DRAW_UNDERL;
2393 #endif

Windows でもフォントを切り替えるようにすればうまくできるのかもしれません。よくわかりませんが。