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

Windows では * レジスタの矩形データの {width} をgetregtype() 関数で正しく取得できない #588

Open
machakann opened this Issue Jul 3, 2014 · 18 comments

Comments

Projects
None yet
5 participants
@machakann

machakann commented Jul 3, 2014

eval.txt によると getregtype() 関数は矩形のデータに対して

      "<CTRL-V>{width}"   for blockwise-visual text

のような値を返すとのことですが、Windows で set clipboard=unnamed していると {width} が常に1を返します。set clipboard= してみると正しい {width} を返すようです。

また、仮想マシン上の linux で set clipboard=unnamedset clipboard=unnamedplus で試してみましたが、再現せず正しい値を返したので、今のところ Windows のみで観測しています。

試したのは以下の環境です。

  • Windows 7 64bit: kaoriya gvim 7.4.274 32bit
    • set clipboard= : ok
    • set clipboard=unnamed : 常に {width} が1!
  • Arch linux 64 bit: (CUI) vim 7.4.307
    • set clipboard= : ok
    • set clipboard=unnamed : ok
    • set clipboard=unnamedplus : ok

再現する方はいらっしゃいませんか?

@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Jul 3, 2014

すいません、書いていませんでしたがそれぞれ v:register を介して getregtype() 関数を使用しています。

machakann commented Jul 3, 2014

すいません、書いていませんでしたがそれぞれ v:register を介して getregtype() 関数を使用しています。

@nocd5

This comment has been minimized.

Show comment
Hide comment
@nocd5

nocd5 Jul 4, 2014

Member

再現しました。Windows XP 32bit gvim/vim 7.4.343
set clipboard=unnamedだけでなく
10l10j"*yなどで
*レジスタに入れても
:echo getregtype()
で^V1となりました。

clip_mch_request_selection(winclip.c)→clip_yank_selection(ops.c)と見てみて
clip_yank_selection内で

str_to_reg(y_ptr, type, str, len, 0L /* blocklen*/ , FALSE);

str_to_reg内で

 if (type == MBLOCK)
    y_ptr->y_width = (blocklen < 0 ? maxlen - 1 : blocklen);

get_reg_type内で

    if (reglen != NULL && y_current->y_type == MBLOCK)
        *reglen = y_current->y_width;

eval.cの
f_getregtype内で

    switch (get_reg_type(regname, &reglen))
    {
    case MLINE: buf[0] = 'V'; break;
    case MCHAR: buf[0] = 'v'; break;
    case MBLOCK:
        buf[0] = Ctrl_V;
        sprintf((char *)buf + 1, "%ld", reglen + 1);
        break;
    }

となってるのが原因でしょうか?

Member

nocd5 commented Jul 4, 2014

再現しました。Windows XP 32bit gvim/vim 7.4.343
set clipboard=unnamedだけでなく
10l10j"*yなどで
*レジスタに入れても
:echo getregtype()
で^V1となりました。

clip_mch_request_selection(winclip.c)→clip_yank_selection(ops.c)と見てみて
clip_yank_selection内で

str_to_reg(y_ptr, type, str, len, 0L /* blocklen*/ , FALSE);

str_to_reg内で

 if (type == MBLOCK)
    y_ptr->y_width = (blocklen < 0 ? maxlen - 1 : blocklen);

get_reg_type内で

    if (reglen != NULL && y_current->y_type == MBLOCK)
        *reglen = y_current->y_width;

eval.cの
f_getregtype内で

    switch (get_reg_type(regname, &reglen))
    {
    case MLINE: buf[0] = 'V'; break;
    case MCHAR: buf[0] = 'v'; break;
    case MBLOCK:
        buf[0] = Ctrl_V;
        sprintf((char *)buf + 1, "%ld", reglen + 1);
        break;
    }

となってるのが原因でしょうか?

@machakann machakann changed the title from Windows で set clipboard=unnamed していると getregtype() 関数の返り値が一部正しくない to Windows では * レジスタの矩形データの {width} をgetregtype() 関数で正しく取得できない Jul 5, 2014

@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Jul 5, 2014

@nocd5 さん、ありがとうございます。少しずれていたみたいなのでタイトルを修正しました。

machakann commented Jul 5, 2014

@nocd5 さん、ありがとうございます。少しずれていたみたいなのでタイトルを修正しました。

@ynkdir

This comment has been minimized.

Show comment
Hide comment
@ynkdir

ynkdir Jul 5, 2014

Member

clipboard= でも ^V1 になりますね。

となってるのが原因でしょうか?

それですね。
クリップボードレジスタの情報を得るために毎回クリップボードからデータをとってきてるんですが、そこに width の情報が入ってないです。
linux の場合はクリップボードの所有というのがあって、vim が所有してるときにはクリップボードからデータをとらなくても自分が保持してる情報が使えるので大丈夫。他の vim でクリップボードにコピーした場合は同じように ^V1 になります。

Member

ynkdir commented Jul 5, 2014

clipboard= でも ^V1 になりますね。

となってるのが原因でしょうか?

それですね。
クリップボードレジスタの情報を得るために毎回クリップボードからデータをとってきてるんですが、そこに width の情報が入ってないです。
linux の場合はクリップボードの所有というのがあって、vim が所有してるときにはクリップボードからデータをとらなくても自分が保持してる情報が使えるので大丈夫。他の vim でクリップボードにコピーした場合は同じように ^V1 になります。

@nocd5

This comment has been minimized.

Show comment
Hide comment
@nocd5

nocd5 Jul 6, 2014

Member

linux以外の場合は、クリップボードの内容取得してwidthを計算しなきゃないんですね。

Member

nocd5 commented Jul 6, 2014

linux以外の場合は、クリップボードの内容取得してwidthを計算しなきゃないんですね。

@ynkdir

This comment has been minimized.

Show comment
Hide comment
@ynkdir

ynkdir Jul 7, 2014

Member

そうですね。
それかクリップボードにwidthの情報も保存するようにするか。

Member

ynkdir commented Jul 7, 2014

そうですね。
それかクリップボードにwidthの情報も保存するようにするか。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 8, 2014

Member

他のツールとの連携もありますし、クリップボードの仕様をvim仕様にするのはどうかなーという気もするので、幅計算にしませんか。

Member

mattn commented Jul 8, 2014

他のツールとの連携もありますし、クリップボードの仕様をvim仕様にするのはどうかなーという気もするので、幅計算にしませんか。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 8, 2014

Member
diff -r b8f703a4e55f src/ops.c
--- a/src/ops.c Fri Jul 04 16:43:17 2014 +0200
+++ b/src/ops.c Tue Jul 08 19:02:40 2014 +0900
@@ -906,6 +906,15 @@
     y_current = &(y_regs[i]);
     if (writing)   /* remember the register we write into for do_put() */
    y_previous = y_current;
+    if (y_current->y_array != NULL && y_current->y_type == MBLOCK)
+    {
+   for (i = 0; i < y_current->y_size; ++i)
+   {
+       int width = mb_string2cells(y_current->y_array[i], -1) - 1;
+       if (y_current->y_width < width)
+       y_current->y_width = width;
+   }
+    }
 }

 #if defined(FEAT_CLIPBOARD) || defined(PROTO)

レビューお願いします。

Member

mattn commented Jul 8, 2014

diff -r b8f703a4e55f src/ops.c
--- a/src/ops.c Fri Jul 04 16:43:17 2014 +0200
+++ b/src/ops.c Tue Jul 08 19:02:40 2014 +0900
@@ -906,6 +906,15 @@
     y_current = &(y_regs[i]);
     if (writing)   /* remember the register we write into for do_put() */
    y_previous = y_current;
+    if (y_current->y_array != NULL && y_current->y_type == MBLOCK)
+    {
+   for (i = 0; i < y_current->y_size; ++i)
+   {
+       int width = mb_string2cells(y_current->y_array[i], -1) - 1;
+       if (y_current->y_width < width)
+       y_current->y_width = width;
+   }
+    }
 }

 #if defined(FEAT_CLIPBOARD) || defined(PROTO)

レビューお願いします。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 8, 2014

Member

あー改行が含まれるのか

↑ パッチ更新ed

Member

mattn commented Jul 8, 2014

あー改行が含まれるのか

↑ パッチ更新ed

@ynkdir

This comment has been minimized.

Show comment
Hide comment
@ynkdir

ynkdir Jul 8, 2014

Member

選択タイプとかのメタデータをクリップボードに保存してるのでそれに追加するといいかなと思ったんですが
winclip.c の VimClipType_t です。
んーでも計算するほうがコード短そうですね。
たぶん幅はスクリーン幅だと思います。

Member

ynkdir commented Jul 8, 2014

選択タイプとかのメタデータをクリップボードに保存してるのでそれに追加するといいかなと思ったんですが
winclip.c の VimClipType_t です。
んーでも計算するほうがコード短そうですね。
たぶん幅はスクリーン幅だと思います。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 8, 2014

Member

パッチ更新しました。↑でlinux以外と読んだので、windows以外の事を考えてこうしました。

Member

mattn commented Jul 8, 2014

パッチ更新しました。↑でlinux以外と読んだので、windows以外の事を考えてこうしました。

@ynkdir

This comment has been minimized.

Show comment
Hide comment
@ynkdir

ynkdir Jul 8, 2014

Member

いいと思います。

Member

ynkdir commented Jul 8, 2014

いいと思います。

@ynkdir

This comment has been minimized.

Show comment
Hide comment
@ynkdir

ynkdir Jul 8, 2014

Member

別件ですが

あい
うx

"あ" にカーソルがあるとして <C-V>jl で "い" も選択されてるけどそのまま y するとコピーされてないという…

Member

ynkdir commented Jul 8, 2014

別件ですが

あい
うx

"あ" にカーソルがあるとして <C-V>jl で "い" も選択されてるけどそのまま y するとコピーされてないという…

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 8, 2014

Member

僕も今ちょうど見つけました。

Member

mattn commented Jul 8, 2014

僕も今ちょうど見つけました。

@mattn

This comment has been minimized.

Show comment
Hide comment
@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Jul 8, 2014

patch をあてて期待通りの動作になることを確認しました。

machakann commented Jul 8, 2014

patch をあてて期待通りの動作になることを確認しました。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 8, 2014

Member

あざます。

Member

mattn commented Jul 8, 2014

あざます。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 10, 2014

Member

@ynkdir linux でなんで動作するか説明を求められてるんですが、現状linux GUI環境が無いので試せません。お手すきに返事して貰えますか。

Member

mattn commented Jul 10, 2014

@ynkdir linux でなんで動作するか説明を求められてるんですが、現状linux GUI環境が無いので試せません。お手すきに返事して貰えますか。

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