New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

マルチバイトを含む行に仮想桁のシンタックスハイライトがマッチしない #704

Closed
Shougo opened this Issue Feb 22, 2015 · 15 comments

Comments

Projects
None yet
3 participants
@Shougo
Member

Shougo commented Feb 22, 2015

Vim 7.4.577 以降で、マルチバイトを含む行に仮想桁位置\%vがマッチしません。

                        */\%v* */\%>v* */\%<v*
\%23v   指定した表示列にマッチします。
\%<23v  指定した表示列より前にマッチします。
\%>23v  指定した表示列より後にマッチします。
    この 3 つを使って、バッファの特定の表示列にマッチできます。文字列
    (|expr-string|) とマッチングするときは、カレントウィンドウの、
    'tabstop' などの設定が使われます。
    "23" の所に表示列番号を指定してください。先頭の番号は 1 です。
    Note: Tab 文字や全角文字などの、複数列で表示される文字の途中の列を指定
    した場合は、マッチしません {Vi にはありません}
    警告: 行を挿入したり削除したりしても、マッチの強調表示は自動的に更新さ
    れません。そのため、このアトムを使った構文強調は、すぐに誤った表示に
    なってしまいます。
    表示列の72桁目以降のすべての文字を強調表示するには次のようにします: >
        /\%>72v.*
<   'hlsearch' をオンにして、カーソルを移動し、テキストを変更してみて、表
    示が更新されるかどうか確認してください。
    17 列までのテキストにマッチさせるには次のようにします: >
        /.*\%17v
<   17 列目も含まれます。なぜならそこに "\%17v" がマッチするからです (たと
    えそれがゼロ幅マッチ (|/zero-width|) だとしても)。ドットを追加してその
    次の文字にマッチさせても結果は同じになります: >
        /.*\%17v.
<   次のコマンドも同様の動作ですが、17 列目に文字が存在しなくてもマッチし
    ます: >
        /.*\%<18v

ドキュメントを見ると、仮想桁はマルチバイトの途中にはマッチしないようですが、今回の問題の場合マルチバイトが含まれると問答無用でマッチしなくなります。

set nocompatible
call append(1,  '▾barbaz')
call append(1,  'foobarbaz')
syntax enable
highlight def link testHighlight PreProc
syntax region testHighlight start='^' end='\%5v' oneline

再現方法:

$ vim -u test.vimrc

  • Vim 7.4.576 以下では'foobarbaz' と '▾barbaz'どちらの行もハイライトされます。
  • Vim 7.4.577 以上(7.4.640 まで確認)では 'foobarbaz' の行のみハイライトされます。

Ubuntu 14.04 環境で確認しました。

Vim 7.4.577 のパッチは以下:
http://ftp.vim.org/vim/patches/7.4/7.4.577

@mattn

This comment has been minimized.

Member

mattn commented Feb 23, 2015

diff -r b64f0df9399c src/regexp_nfa.c
--- a/src/regexp_nfa.c  Tue Feb 17 17:50:26 2015 +0100
+++ b/src/regexp_nfa.c  Mon Feb 23 09:20:00 2015 +0900
@@ -6477,8 +6477,17 @@

            /* Bail out quickly when there can't be a match, avoid the
             * overhead of win_linetabsize() on long lines. */
-           if (op != 1 && col > t->state->val)
-           break;
+#ifdef FEAT_MBYTE
+           if (has_mbyte)
+           {
+           if (op != 1 && col > t->state->val +
+               (*mb_ptr2cells)((char_u *)reginput))
+               break;
+           }
+           else
+#endif
+           if (op != 1 && col > t->state->val)
+               break;
            result = FALSE;
            if (op == 1 && col - 1 > t->state->val && col > 100)
            {
@mattn

This comment has been minimized.

Member

mattn commented Feb 23, 2015

そもそもASCIIだとしても1セル少ない気がする

@mattn

This comment has been minimized.

Member

mattn commented Feb 23, 2015

あ、あってるか

@h-east

This comment has been minimized.

Member

h-east commented Feb 23, 2015

test追加した方が良い気がする。test95

@mattn

This comment has been minimized.

Member

mattn commented Feb 23, 2015

あいう

というバッファで

/^.*\%5

ってやるのと

/.*\%5

ってやるので結果が違うけど、いいんだっけ。

@Shougo

This comment has been minimized.

Member

Shougo commented Feb 24, 2015

@mattn 修正ありがとうございます。
Vim 7.4.640 環境でパッチを適用したところ、上記の問題が解決することを確認しました。

しかし、 mattn さんのパッチでも別のパターンはうまくマッチしないことが分かりました。

set nocompatible
call append(1,  'baあrbaz')
call append(1,  '▾aあrbaz')
syntax enable
highlight def link testHighlight PreProc
syntax region testHighlight start='^' end='\%5v' oneline

再現方法:

$ vim -u test.vimrc
  • Vim 7.4.576 以下では'baあrbaz' と '▾aあrbaz'どちらの行もハイライトされます。
  • Vim 7.4.577 以上では mattn さんのパッチを適用しても 'baあrbaz' の行のみハイライトされます。

お手数ですが確認をよろしくお願いします。

@mattn

This comment has been minimized.

Member

mattn commented Feb 25, 2015

あー、ここそもそもオリジナルからバイト数と文字幅の混同があるっぽい。

@mattn

This comment has been minimized.

Member

mattn commented Feb 25, 2015

diff -r b64f0df9399c src/regexp_nfa.c
--- a/src/regexp_nfa.c  Tue Feb 17 17:50:26 2015 +0100
+++ b/src/regexp_nfa.c  Thu Feb 26 02:58:43 2015 +0900
@@ -6474,20 +6474,20 @@
            int     op = t->state->c - NFA_VCOL;
            colnr_T col = (colnr_T)(reginput - regline);
            win_T   *wp = reg_win == NULL ? curwin : reg_win;
+           int ts = wp->w_buffer->b_p_ts;
+
+           /* Guess that a character won't use more columns than
+            * 'tabstop', with a minimum of 4. */
+           if (ts < 4)
+           ts = 4;

            /* Bail out quickly when there can't be a match, avoid the
             * overhead of win_linetabsize() on long lines. */
-           if (op != 1 && col > t->state->val)
+           if (op != 1 && col > t->state->val * ts)
            break;
            result = FALSE;
            if (op == 1 && col - 1 > t->state->val && col > 100)
            {
-           int ts = wp->w_buffer->b_p_ts;
-
-           /* Guess that a character won't use more columns than
-            * 'tabstop', with a minimum of 4. */
-           if (ts < 4)
-               ts = 4;
            result = col > t->state->val * ts;
            }
            if (!result)

これで行けるかと思います。
今回のバグは、高速化の為に、文字オフセットでスキップする処理が入っているのですが、タブ文字を使うと1文字最大4になり得るのでその考慮が無かったのが原因です。
vimが扱えるマルチバイト幅の最大は2なのでts=4のスキップ処理があればマルチバイト対応は必要無いです。

@Shougo

This comment has been minimized.

Member

Shougo commented Feb 28, 2015

ありがとうございます。Vim 7.4.640 に上記パッチを適用し、動作することを確認しました。
完璧です。
vim_dev へのパッチの投稿をお願いしてよろしいでしょうか。

@mattn

This comment has been minimized.

Member

mattn commented Mar 2, 2015

テスト書いてないです。

@mattn

This comment has been minimized.

Member

mattn commented Mar 2, 2015

ちょっとパッチ変えてひとまず投げました。

https://groups.google.com/d/msg/vim_dev/zQ4kpoWE8JU/vdok28aSl14J

@h-east

This comment has been minimized.

Member

h-east commented Mar 3, 2015

todoリスト入り。

Patch to make 7.4.582 work for multi-byte. (Yasuhiro Matsumoto, 2015 Mar 1)

注: Patch 7.4.582 は 7.4.577 の別件のbugfix

vim-jp/vim@9ce3a17#diff-38d7929bd26d74d92ceddf984bbfc8dbR101

「テストはいかが?」と言われているのでOpen状態のままにしときます。
mattn さん以外の人がテスト書いてもいいんですよ?

@Shougo

This comment has been minimized.

Member

Shougo commented Mar 3, 2015

@mattn 対応ありがとうございます。

@h-east

This comment has been minimized.

Member

h-east commented Mar 6, 2015

Patch 7.4.651
https://groups.google.com/d/msg/vim_dev/hhvBEpqEsc8/R8acZD8tRL4J

ノーテストで取り込まれてしもうた。

@Shougo

This comment has been minimized.

Member

Shougo commented Mar 7, 2015

修正を確認しました。対応ありがとうございました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment