Closed iranoan closed 1 year ago
以下の手順とscriptで再現しました。(Vim 9.0.1128 on Fedora 32 via PuTTY 0.73)
用意するファイル
~/.vim/pack/my/start/sample/plugin/sample.vim
vim9script
augroup SAMPLE
autocmd!
autocmd CmdlineEnter * sample#Init()
augroup END
~/.vim/pack/my/start/sample/autoload/sample.vim
vim9script
export def Init(): void
cnoremap <expr>" <SID>Quote('"')
enddef
def Quote(str: string): string
def InPair(): number
return 0
enddef
return str
enddef
再現手順
$ vim -Nu NORC
:"
期待する動作
コマンドラインに :"
が表示される。
実際の動作
"
が改行されてから表示される。(下記画像参照)
再現条件に必要なのは:def
のネストのようです。
実際に改行している部分は以下の userfunc.c の define_function()
内の msg_putchar('\n');
なのですが、今回の現象とコメント // don't overwrite the function name
が結びつかないんですよね。
if
の判定が足りていないのか、この動作が仕様なのか。。
/*
* Read the body of the function, until "}", ":endfunction" or ":enddef" is
* found.
*/
if (KeyTyped)
{
// Check if the function already exists, don't let the user type the
// whole function before telling him it doesn't work! For a script we
// need to skip the body to be able to find what follows.
if (!eap->skip && !eap->forceit)
{
if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
emsg(_(e_dictionary_entry_already_exists));
else if (name != NULL && find_func(name, is_global) != NULL)
emsg_funcname(e_function_str_already_exists_add_bang_to_replace, name);
}
if (!eap->skip && did_emsg)
goto erret;
msg_putchar('\n'); // don't overwrite the function name
cmdline_row = msg_row;
}
backtraceも載せときます(関連部分のみ)
~
#8 0x0000000000706ed0 in msg_putchar (c=10) at message.c:1518
#9 0x00000000006653aa in define_function
(eap=0x7ffdc108fe30, name_arg=0x1fd0ec0 "<lambda>2", lines_to_free=0x7ffdc10
901c0, in_class=0) at userfunc.c:4892
#10 0x00000000006730b5 in compile_nested_function
(eap=0x7ffdc108fe30, cctx=0x7ffdc1090030, lines_to_free=0x7ffdc10901c0)
at vim9compile.c:1004
#11 0x0000000000678774 in compile_def_function
(ufunc=0x20229a0, check_return_type=0, compile_type=CT_NONE, outer_cctx=0x0)
at vim9compile.c:3421
#12 0x00000000006878ae in call_def_function
(ufunc=0x20229a0, argc_arg=1, argv=0x7ffdc1090d90, flags=0, partial=0x0, obj
ect=0x0, funccal=0x1fcd560, rettv=0x7ffdc1091840) at vim9execute.c:5684
#13 0x0000000000660ef3 in call_user_func
(fp=0x20229a0, argcount=1, argvars=0x7ffdc1090d90, rettv=0x7ffdc1091840, fun
cexe=0x7ffdc1090f40, selfdict=0x0) at userfunc.c:2771
#14 0x0000000000661f3d in call_user_func_check
(fp=0x20229a0, argcount=1, argvars=0x7ffdc1090d90, rettv=0x7ffdc1091840, fun
cexe=0x7ffdc1090f40, selfdict=0x0) at userfunc.c:3189
#15 0x0000000000662d1e in call_func
(funcname=0x20207b0 "\200\375R15_Quote('\"')", len=11, rettv=0x7ffdc1091840,
argcount_in=1, argvars_in=0x7ffdc1090d90, funcexe=0x7ffdc1090f40)
at userfunc.c:3745
#16 0x000000000065f61c in get_func_tv
(name=0x20207b0 "\200\375R15_Quote('\"')", len=11, rettv=0x7ffdc1091840, arg
=0x7ffdc1091710, evalarg=0x7ffdc10917b0, funcexe=0x7ffdc1090f40)
at userfunc.c:1923
#17 0x000000000046d005 in eval_func
(arg=0x7ffdc1091710, evalarg=0x7ffdc10917b0, name=0x2036ca0 "\200\375R15_Quo
te('\"')", name_len=11, rettv=0x7ffdc1091840, flags=1, basetv=0x0)
at eval.c:2335
~
vim_devに報告しました。 https://github.com/vim/vim/issues/11773
詳しく検証していただきありがとうございます
再現条件に必要なのは:defのネストのようです。 確かに def が多いと改行も多くなりますね
defコンパイル時になんかあるのかな
Patch 9.0.1130で修正されました。
scriptのロード中かつ関数ネスト中は KeyTyped
(キー入力したよフラグ)をリセットする修正で現象を回避するようにしたようです。
質問の内容
function で定義した関数では起きないのですが、def 関数で定義した関数だと、最初の使用時にスクロールが発生するケースが有ります 結果、入力中のコマンドが途切れているように見えますが、コマンド自体は問題なく動作します 初回時だけで、2 度目以降は起きません これは仕様なのでしょうか?
再現する設定とプラグイン例は次のとおりです \~/.vim/vimrc
\~/.vim/pack/sample/start/sample/plugin/sample.vim
\~/.vim/pack/sample/start/sample/autoload/sample.vim
関数がある程度複雑になると発生するようで、上記例の場合 InPair() を態々関数にしなければ問題は起きません またコメントに有るように、初期化時に defcompile すれば、関数の複雑さに関係なく問題は起きません
Vimのバージョン
OSの種類/ディストリ/バージョン