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

timerで起動した後にコマンドラインに文字が現れる #1058

Closed
rickhowe opened this Issue Jul 25, 2017 · 45 comments

Comments

Projects
None yet
4 participants
@rickhowe

rickhowe commented Jul 25, 2017

ウィンドウが複数ある場合、
次のようなtimerを使用したコマンド T で関数 T() を起動した後に
:、/、? でコマンドラインモードにすると、文字 'b' が現れます。
どうやら入力ストリームに文字が入ってしまっているようです。

function! T(...)
	if winnr('$') > 1
		call system('path')
		wincmd w
	endif
endfunction
command! T call timer_start(0, 'T')

いろいろと調べてみた結果、この現象は

  • timerを使う
  • guiのみ
  • shelltempがオン
  • system()直後に別のウィンドウに移動する

の場合に再現するようです。

この現象は patch 0670 から発生し始め、この時の出現文字は 'a' でした。
patch 0697 からは文字が 'b' に変わりました。
最新の patch 0771 でも再現します。

Windows 7 でしか確認できませんが、その他の OS でも再現するでしょうか?

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

Windows 7 で確認しましたが、再現しませんでした。
terminal

Member

mattn commented Jul 25, 2017

Windows 7 で確認しましたが、再現しませんでした。
terminal

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

あ、GUI でしたね。もっかい試します。

Member

mattn commented Jul 25, 2017

あ、GUI でしたね。もっかい試します。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

んー。再現なしです。

terminal

Member

mattn commented Jul 25, 2017

んー。再現なしです。

terminal

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Jul 25, 2017

Member

https://github.com/vim/vim-win32-installer/releases/tag/v8.0.0771 の gvim_8.0.0771_x64.zip の gvim.exe をWindows 7 で動かしたら再現しました。

Gvim 8.0.771 (Huge with GTK2-GNOME) on fedora 25 では再現しませんでした。
家に帰ったらWindows 10で試してみます。

Member

h-east commented Jul 25, 2017

https://github.com/vim/vim-win32-installer/releases/tag/v8.0.0771 の gvim_8.0.0771_x64.zip の gvim.exe をWindows 7 で動かしたら再現しました。

Gvim 8.0.771 (Huge with GTK2-GNOME) on fedora 25 では再現しませんでした。
家に帰ったらWindows 10で試してみます。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Jul 25, 2017

Member

Linuxの時はT関数内の

        call system('path')

        call system('env | grep PATH')

に変更してやってます。あんまり関係ないとは思いますが。

Member

h-east commented Jul 25, 2017

Linuxの時はT関数内の

        call system('path')

        call system('env | grep PATH')

に変更してやってます。あんまり関係ないとは思いますが。

@h-east h-east added the kind/bug label Jul 25, 2017

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

あ、コマンドラインモードにする手順が抜けてました。

Member

mattn commented Jul 25, 2017

あ、コマンドラインモードにする手順が抜けてました。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

再現しました。master/HEAD です。

Member

mattn commented Jul 25, 2017

再現しました。master/HEAD です。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

gui_focus_change で送ってるフォーカスですかね。

    void
gui_focus_change(int in_focus)
{
/*
 * Skip this code to avoid drawing the cursor when debugging and switching
 * between the debugger window and gvim.
 */
#if 1
    gui.in_focus = in_focus;
    out_flush();		/* make sure output has been written */
    gui_update_cursor(TRUE, FALSE);

# ifdef FEAT_XIM
    xim_set_focus(in_focus);
# endif

    /* Put events in the input queue only when allowed.
     * ui_focus_change() isn't called directly, because it invokes
     * autocommands and that must not happen asynchronously. */
    if (!hold_gui_events)
    {
	char_u  bytes[3];

	bytes[0] = CSI;
	bytes[1] = KS_EXTRA;
	bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
	add_to_input_buf(bytes, 3);
    }
#endif
}
Member

mattn commented Jul 25, 2017

gui_focus_change で送ってるフォーカスですかね。

    void
gui_focus_change(int in_focus)
{
/*
 * Skip this code to avoid drawing the cursor when debugging and switching
 * between the debugger window and gvim.
 */
#if 1
    gui.in_focus = in_focus;
    out_flush();		/* make sure output has been written */
    gui_update_cursor(TRUE, FALSE);

# ifdef FEAT_XIM
    xim_set_focus(in_focus);
# endif

    /* Put events in the input queue only when allowed.
     * ui_focus_change() isn't called directly, because it invokes
     * autocommands and that must not happen asynchronously. */
    if (!hold_gui_events)
    {
	char_u  bytes[3];

	bytes[0] = CSI;
	bytes[1] = KS_EXTRA;
	bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
	add_to_input_buf(bytes, 3);
    }
#endif
}
@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

本来 call_shell/mch_call_shell 実行中には hold_gui_events でフォーカスイベントがガードされているはずなのだけど、Windows の mch_call_system 実行中に届いたイベントがこのガード終了後にやってきて期待しない状態で KS_EXTRA を input_buf に差し込まれてしまってキーシーケンスに KE_FOCUSGAINED (98 'b')が混じるらしい。

Member

mattn commented Jul 25, 2017

本来 call_shell/mch_call_shell 実行中には hold_gui_events でフォーカスイベントがガードされているはずなのだけど、Windows の mch_call_system 実行中に届いたイベントがこのガード終了後にやってきて期待しない状態で KS_EXTRA を input_buf に差し込まれてしまってキーシーケンスに KE_FOCUSGAINED (98 'b')が混じるらしい。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 25, 2017

Member

てかコメントに書いてある that must not happen asynchronously. が起きてしまっているって奴か。

Member

mattn commented Jul 25, 2017

てかコメントに書いてある that must not happen asynchronously. が起きてしまっているって奴か。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 26, 2017

Member
diff --git a/src/gui_w32.c b/src/gui_w32.c
index a91e0710b..270462f44 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2913,8 +2913,11 @@ _OnSetFocus(
     HWND hwnd,
     HWND hwndOldFocus)
 {
-    gui_focus_change(TRUE);
-    s_getting_focus = TRUE;
+    if (s_getting_focus == FALSE)
+    {
+	gui_focus_change(TRUE);
+	s_getting_focus = TRUE;
+    }
     (void)MyWindowProc(hwnd, WM_SETFOCUS, (WPARAM)hwndOldFocus, 0);
 }
 
@@ -2923,8 +2926,11 @@ _OnKillFocus(
     HWND hwnd,
     HWND hwndNewFocus)
 {
-    gui_focus_change(FALSE);
-    s_getting_focus = FALSE;
+    if (s_getting_focus == TRUE)
+    {
+	gui_focus_change(FALSE);
+	s_getting_focus = FALSE;
+    }
     (void)MyWindowProc(hwnd, WM_KILLFOCUS, (WPARAM)hwndNewFocus, 0);
 }
 

ワークアラウンドっぽいけどこれで直る様です。数日試して直ってそうなら送ります。

Member

mattn commented Jul 26, 2017

diff --git a/src/gui_w32.c b/src/gui_w32.c
index a91e0710b..270462f44 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2913,8 +2913,11 @@ _OnSetFocus(
     HWND hwnd,
     HWND hwndOldFocus)
 {
-    gui_focus_change(TRUE);
-    s_getting_focus = TRUE;
+    if (s_getting_focus == FALSE)
+    {
+	gui_focus_change(TRUE);
+	s_getting_focus = TRUE;
+    }
     (void)MyWindowProc(hwnd, WM_SETFOCUS, (WPARAM)hwndOldFocus, 0);
 }
 
@@ -2923,8 +2926,11 @@ _OnKillFocus(
     HWND hwnd,
     HWND hwndNewFocus)
 {
-    gui_focus_change(FALSE);
-    s_getting_focus = FALSE;
+    if (s_getting_focus == TRUE)
+    {
+	gui_focus_change(FALSE);
+	s_getting_focus = FALSE;
+    }
     (void)MyWindowProc(hwnd, WM_KILLFOCUS, (WPARAM)hwndNewFocus, 0);
 }
 

ワークアラウンドっぽいけどこれで直る様です。数日試して直ってそうなら送ります。

@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Jul 26, 2017

すいません、私のところではまだ再現するようです。
set noshelltemp で再現しないのが不思議です。

rickhowe commented Jul 26, 2017

すいません、私のところではまだ再現するようです。
set noshelltemp で再現しないのが不思議です。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 26, 2017

Member

set noshelltemp の場合は、コマンドプロンプトの起動方法が異なっていてフォーカスが外れないのです。

Member

mattn commented Jul 26, 2017

set noshelltemp の場合は、コマンドプロンプトの起動方法が異なっていてフォーカスが外れないのです。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 26, 2017

Member

set shelltemp の場合はコマンドプロンプトに一度フォーカスが移り、終了後に vim に戻ってきますが、その際のイベントが外部コマンド実行後に戻ってきてしまうというバグです。

Member

mattn commented Jul 26, 2017

set shelltemp の場合はコマンドプロンプトに一度フォーカスが移り、終了後に vim に戻ってきますが、その際のイベントが外部コマンド実行後に戻ってきてしまうというバグです。

@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Jul 26, 2017

このバグは patch 0670 の修正方法を工夫すれば治るものでしょうか?

rickhowe commented Jul 26, 2017

このバグは patch 0670 の修正方法を工夫すれば治るものでしょうか?

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 27, 2017

Member
diff --git a/src/getchar.c b/src/getchar.c
index 3decef3f5..c4ec5cd8c 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1984,7 +1984,7 @@ vgetorpeek(int advance)
      * Using ":normal" can also do this, but it saves the typeahead buffer,
      * thus it should be OK.  But don't get a key from the user then.
      */
-    if (vgetc_busy > 0 && ex_normal_busy == 0)
+    if (vgetc_busy > 0 && ex_normal_busy == 0 && timer_busy > 0)
 	return NUL;
 
     local_State = get_real_state();

これでどうでしょうか? cc: @ichizok

Member

mattn commented Jul 27, 2017

diff --git a/src/getchar.c b/src/getchar.c
index 3decef3f5..c4ec5cd8c 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1984,7 +1984,7 @@ vgetorpeek(int advance)
      * Using ":normal" can also do this, but it saves the typeahead buffer,
      * thus it should be OK.  But don't get a key from the user then.
      */
-    if (vgetc_busy > 0 && ex_normal_busy == 0)
+    if (vgetc_busy > 0 && ex_normal_busy == 0 && timer_busy > 0)
 	return NUL;
 
     local_State = get_real_state();

これでどうでしょうか? cc: @ichizok

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 27, 2017

Member

あ、だめすね。。。考え直し。

Member

mattn commented Jul 27, 2017

あ、だめすね。。。考え直し。

@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Jul 27, 2017

まだ再現します。

rickhowe commented Jul 27, 2017

まだ再現します。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 27, 2017

Member

はい。↑のでは直らないと思います。いま試行錯誤中です。

Member

mattn commented Jul 27, 2017

はい。↑のでは直らないと思います。いま試行錯誤中です。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jul 27, 2017

Member
diff --git a/src/gui.c b/src/gui.c
index ff81d0b74..d4c75259d 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4793,7 +4793,7 @@ gui_focus_change(int in_focus)
     /* Put events in the input queue only when allowed.
      * ui_focus_change() isn't called directly, because it invokes
      * autocommands and that must not happen asynchronously. */
-    if (!hold_gui_events)
+    if (!hold_gui_events && timer_busy == 0)
     {
 	char_u  bytes[3];
 

これで直る(というかフォーカスイベントを捨てる)様な気はするんですが、ワークアラウンドなんですよねー。。。

いっそ CSI を feedkeys で投げてやるって手はあるかも。

Member

mattn commented Jul 27, 2017

diff --git a/src/gui.c b/src/gui.c
index ff81d0b74..d4c75259d 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4793,7 +4793,7 @@ gui_focus_change(int in_focus)
     /* Put events in the input queue only when allowed.
      * ui_focus_change() isn't called directly, because it invokes
      * autocommands and that must not happen asynchronously. */
-    if (!hold_gui_events)
+    if (!hold_gui_events && timer_busy == 0)
     {
 	char_u  bytes[3];
 

これで直る(というかフォーカスイベントを捨てる)様な気はするんですが、ワークアラウンドなんですよねー。。。

いっそ CSI を feedkeys で投げてやるって手はあるかも。

@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Jul 27, 2017

はい、直ってますね。

rickhowe commented Jul 27, 2017

はい、直ってますね。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 27, 2017

Member

sleep 内で timer を発火させた場合はどうなりますか?
これで再現した場合、670以前でも確認してみてもらえますか。

function! T(...)
  if winnr('$') > 1
    call system('path')
    wincmd w
  endif
endfunction
function! F()
  call timer_start(0, 'T')
  sleep 1m
endfunction
command! T call F()
Member

ichizok commented Jul 27, 2017

sleep 内で timer を発火させた場合はどうなりますか?
これで再現した場合、670以前でも確認してみてもらえますか。

function! T(...)
  if winnr('$') > 1
    call system('path')
    wincmd w
  endif
endfunction
function! F()
  call timer_start(0, 'T')
  sleep 1m
endfunction
command! T call F()
@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Jul 27, 2017

これも再現しませんが、この gui.c の修正がなくても再現しないようです。
sleep 1m を外すと、今回の修正がないと再現します。

rickhowe commented Jul 27, 2017

これも再現しませんが、この gui.c の修正がなくても再現しないようです。
sleep 1m を外すと、今回の修正がないと再現します。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 31, 2017

Member

GVim 8.0.0823 with gtk3 on Ubuntu 16.04 で再現できました。

test.vim

function! T(...)
  call system('xterm -e "sleep 1"')
  if winnr('$') > 1
    wincmd w
  else
    new
  endif
endfunction
call timer_start(0, 'T')

:so test.vim

Member

ichizok commented Jul 31, 2017

GVim 8.0.0823 with gtk3 on Ubuntu 16.04 で再現できました。

test.vim

function! T(...)
  call system('xterm -e "sleep 1"')
  if winnr('$') > 1
    wincmd w
  else
    new
  endif
endfunction
call timer_start(0, 'T')

:so test.vim

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 31, 2017

Member

call system('xterm -e "sleep 1"') するとフォーカスが xterm に移って、終わったら Vim に戻りますが、
この時 FocusLost FocusGained イベントが発生しないことがあります。

Member

ichizok commented Jul 31, 2017

call system('xterm -e "sleep 1"') するとフォーカスが xterm に移って、終わったら Vim に戻りますが、
この時 FocusLost FocusGained イベントが発生しないことがあります。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 31, 2017

Member

typebuf の方に入れると良さそうですが(Ubuntu 16.04 で確認)、影響度が不明。test は通りました。

--- a/src/gui.c
+++ b/src/gui.c
@@ -4795,12 +4795,14 @@ gui_focus_change(int in_focus)
      * autocommands and that must not happen asynchronously. */
     if (!hold_gui_events)
     {
-       char_u  bytes[3];
+       char_u  bytes[4];

        bytes[0] = CSI;
        bytes[1] = KS_EXTRA;
        bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
-       add_to_input_buf(bytes, 3);
+       bytes[3] = NUL;
+       typebuf_was_filled = TRUE;
+       (void)ins_typebuf(bytes, REMAP_NONE, 0, TRUE, FALSE);
     }
 #endif
 }
Member

ichizok commented Jul 31, 2017

typebuf の方に入れると良さそうですが(Ubuntu 16.04 で確認)、影響度が不明。test は通りました。

--- a/src/gui.c
+++ b/src/gui.c
@@ -4795,12 +4795,14 @@ gui_focus_change(int in_focus)
      * autocommands and that must not happen asynchronously. */
     if (!hold_gui_events)
     {
-       char_u  bytes[3];
+       char_u  bytes[4];

        bytes[0] = CSI;
        bytes[1] = KS_EXTRA;
        bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
-       add_to_input_buf(bytes, 3);
+       bytes[3] = NUL;
+       typebuf_was_filled = TRUE;
+       (void)ins_typebuf(bytes, REMAP_NONE, 0, TRUE, FALSE);
     }
 #endif
 }
@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 31, 2017

Member

これは feedkeys() で投げるのと同じことですね。

Member

ichizok commented Jul 31, 2017

これは feedkeys() で投げるのと同じことですね。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 31, 2017

Member

wincmd の中で vgetorpeek() が呼ばれるんですが、8.0.0670 の変更で
timer callback 中でも vgetorpeek() が下まで実行されるようになり、inbuftypebuf.tb_buf の取得が発生します。

#0  0x00000000005e5fde in read_from_input_buf (buf=0x8ff65a <typebuf_init+58> "\233\375b~tr\t\200kb\200kb/tr\tvim_\ti\t\r/\200kb:so\200ku\r/", maxlen=3) at ui.c:1758
#1  0x00000000005e3c65 in ui_inchar (buf=0x8ff65a <typebuf_init+58> "\233\375b~tr\t\200kb\200kb/tr\tvim_\ti\t\r/\200kb:so\200ku\r/", maxlen=68, wtime=0, tb_change_cnt=68
) at ui.c:187
#2  0x00000000004babc5 in inchar (buf=0x8ff65a <typebuf_init+58> "\233\375b~tr\t\200kb\200kb/tr\tvim_\ti\t\r/\200kb:so\200ku\r/", maxlen=206, wait_time=0, tb_change_cnt=
68) at getchar.c:3065
#3  0x00000000004ba78f in vgetorpeek (advance=0) at getchar.c:2841
#4  0x00000000004b8d5c in vpeekc () at getchar.c:1842
#5  0x00000000004b8e08 in char_avail () at getchar.c:1898
#6  0x00000000004f7efb in update_mouseshape (shape_idx=-1) at misc2.c:3774
#7  0x00000000005da435 in setmouse () at term.c:3532
#8  0x00000000005ff95c in win_enter_ext (wp=0xe386e0, undo_sync=1, curwin_invalid=0, trigger_new_autocmds=0, trigger_enter_autocmds=1, trigger_leave_autocmds=1)
    at window.c:4476
#9  0x00000000005ff565 in win_enter (wp=0xe386e0, undo_sync=1) at window.c:4348
#10 0x00000000005ff169 in win_goto (wp=0xe386e0) at window.c:4167
#11 0x00000000005f8b69 in do_window (nchar=119, Prenum=0, xchar=0) at window.c:266
#12 0x0000000000486cae in ex_wincmd (eap=0x7ffd88bcb380) at ex_docmd.c:9310
(snip)
typebuf.tb_len = 3
typebuf.tb_buf[typebuf.tb_off + 0] = '\233'
typebuf.tb_buf[typebuf.tb_off + 1] = '\375'
typebuf.tb_buf[typebuf.tb_off + 2] = 'b'

この typebuf が消費されないまま timer callback 後に入力を受けることになり、以下の状態になります。
/ を入力した場合)

typebuf.tb_len = 3
typebuf.tb_buf[typebuf.tb_off + 0] = '/'
typebuf.tb_buf[typebuf.tb_off + 1] = '\000'
typebuf.tb_buf[typebuf.tb_off + 2] = 'b'

これが処理され、/b となります。

Member

ichizok commented Jul 31, 2017

wincmd の中で vgetorpeek() が呼ばれるんですが、8.0.0670 の変更で
timer callback 中でも vgetorpeek() が下まで実行されるようになり、inbuftypebuf.tb_buf の取得が発生します。

#0  0x00000000005e5fde in read_from_input_buf (buf=0x8ff65a <typebuf_init+58> "\233\375b~tr\t\200kb\200kb/tr\tvim_\ti\t\r/\200kb:so\200ku\r/", maxlen=3) at ui.c:1758
#1  0x00000000005e3c65 in ui_inchar (buf=0x8ff65a <typebuf_init+58> "\233\375b~tr\t\200kb\200kb/tr\tvim_\ti\t\r/\200kb:so\200ku\r/", maxlen=68, wtime=0, tb_change_cnt=68
) at ui.c:187
#2  0x00000000004babc5 in inchar (buf=0x8ff65a <typebuf_init+58> "\233\375b~tr\t\200kb\200kb/tr\tvim_\ti\t\r/\200kb:so\200ku\r/", maxlen=206, wait_time=0, tb_change_cnt=
68) at getchar.c:3065
#3  0x00000000004ba78f in vgetorpeek (advance=0) at getchar.c:2841
#4  0x00000000004b8d5c in vpeekc () at getchar.c:1842
#5  0x00000000004b8e08 in char_avail () at getchar.c:1898
#6  0x00000000004f7efb in update_mouseshape (shape_idx=-1) at misc2.c:3774
#7  0x00000000005da435 in setmouse () at term.c:3532
#8  0x00000000005ff95c in win_enter_ext (wp=0xe386e0, undo_sync=1, curwin_invalid=0, trigger_new_autocmds=0, trigger_enter_autocmds=1, trigger_leave_autocmds=1)
    at window.c:4476
#9  0x00000000005ff565 in win_enter (wp=0xe386e0, undo_sync=1) at window.c:4348
#10 0x00000000005ff169 in win_goto (wp=0xe386e0) at window.c:4167
#11 0x00000000005f8b69 in do_window (nchar=119, Prenum=0, xchar=0) at window.c:266
#12 0x0000000000486cae in ex_wincmd (eap=0x7ffd88bcb380) at ex_docmd.c:9310
(snip)
typebuf.tb_len = 3
typebuf.tb_buf[typebuf.tb_off + 0] = '\233'
typebuf.tb_buf[typebuf.tb_off + 1] = '\375'
typebuf.tb_buf[typebuf.tb_off + 2] = 'b'

この typebuf が消費されないまま timer callback 後に入力を受けることになり、以下の状態になります。
/ を入力した場合)

typebuf.tb_len = 3
typebuf.tb_buf[typebuf.tb_off + 0] = '/'
typebuf.tb_buf[typebuf.tb_off + 1] = '\000'
typebuf.tb_buf[typebuf.tb_off + 2] = 'b'

これが処理され、/b となります。

@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Aug 3, 2017

この不具合を修正するのは難しいでしょうか?
system() 直前に shelltemp をオフにすると発生しませんが、
shelltemp の help に、
「system() 関数はこのオプションを参照せず常に一時ファイルを利用する」
との記述があります。これは回避策にならないでしょうか?
パイプが使えないシステムでの回避策も不明ですので躊躇しています。

rickhowe commented Aug 3, 2017

この不具合を修正するのは難しいでしょうか?
system() 直前に shelltemp をオフにすると発生しませんが、
shelltemp の help に、
「system() 関数はこのオプションを参照せず常に一時ファイルを利用する」
との記述があります。これは回避策にならないでしょうか?
パイプが使えないシステムでの回避策も不明ですので躊躇しています。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 3, 2017

Member

この不具合を修正するのは難しいでしょうか?

はい。shelltemp を有効にする無効にするはユーザの決定次第なのです。Windows の場合 shelltemp を使うとコマンドプロンプトを最小化状態で起動しますが、これは万が一コマンドがハングした場合にそのコマンドプロンプトを x で閉じれる事を想定しています。

Member

mattn commented Aug 3, 2017

この不具合を修正するのは難しいでしょうか?

はい。shelltemp を有効にする無効にするはユーザの決定次第なのです。Windows の場合 shelltemp を使うとコマンドプロンプトを最小化状態で起動しますが、これは万が一コマンドがハングした場合にそのコマンドプロンプトを x で閉じれる事を想定しています。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 3, 2017

Member

#1058 (comment)
実際 typebuf に入れるのはダメなんでしょうか?

Member

ichizok commented Aug 3, 2017

#1058 (comment)
実際 typebuf に入れるのはダメなんでしょうか?

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 3, 2017

Member

すみません。そこがちょっと見えてないんです。例えばキーシーケンスの途中に入ってきたりした場合にどう作用するのか。

Member

mattn commented Aug 3, 2017

すみません。そこがちょっと見えてないんです。例えばキーシーケンスの途中に入ってきたりした場合にどう作用するのか。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 3, 2017

Member

一度 vim-dev に投げてみますか?

Member

mattn commented Aug 3, 2017

一度 vim-dev に投げてみますか?

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 3, 2017

Member

そうですね。確認してみます。

Member

ichizok commented Aug 3, 2017

そうですね。確認してみます。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 3, 2017

Member

#1058 (comment)
他の方の環境でもこれで直りますか?

Member

ichizok commented Aug 3, 2017

#1058 (comment)
他の方の環境でもこれで直りますか?

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 3, 2017

Member

はい。Windows では(例外的な確認はしてませんが)直っていました。

Member

mattn commented Aug 3, 2017

はい。Windows では(例外的な確認はしてませんが)直っていました。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 3, 2017

Member

一応、ciwci までタイプ、ウィンドウフォーカス切り替え、w をタイプして大丈夫なのでたぶん問題ないと思います。

Member

mattn commented Aug 3, 2017

一応、ciwci までタイプ、ウィンドウフォーカス切り替え、w をタイプして大丈夫なのでたぶん問題ないと思います。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 4, 2017

Member

branch 作って CI 回したら、Appveyor が fail してました、、
https://ci.appveyor.com/project/ichizok/vim/build/385/job/cd0ktrtdkk47p472

Member

ichizok commented Aug 4, 2017

branch 作って CI 回したら、Appveyor が fail してました、、
https://ci.appveyor.com/project/ichizok/vim/build/385/job/cd0ktrtdkk47p472

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 4, 2017

Member

改修内容と関係なさそうですけどねー。

Member

mattn commented Aug 4, 2017

改修内容と関係なさそうですけどねー。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 5, 2017

Member

そう思ったんですが、変更を戻すと通るので...
別の修正を入れてみました。こちらは CI 通りました。
https://github.com/vim/vim/compare/master...ichizok:fix/gui-focus.diff

Member

ichizok commented Aug 5, 2017

そう思ったんですが、変更を戻すと通るので...
別の修正を入れてみました。こちらは CI 通りました。
https://github.com/vim/vim/compare/master...ichizok:fix/gui-focus.diff

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Aug 5, 2017

Member

Windows で確認しました。動いてそうです。

Member

mattn commented Aug 5, 2017

Windows で確認しました。動いてそうです。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 5, 2017

Member

確認ありがとうございます。投げました。
vim/vim#1940

Member

ichizok commented Aug 5, 2017

確認ありがとうございます。投げました。
vim/vim#1940

@rickhowe

This comment has been minimized.

Show comment
Hide comment
@rickhowe

rickhowe Aug 5, 2017

Windows 7 だけでしか試せませんが、直ってます。

rickhowe commented Aug 5, 2017

Windows 7 だけでしか試せませんが、直ってます。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok
Member

ichizok commented Aug 30, 2017

8.0.1020
vim/vim@0f0f230

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 30, 2017

Member

CUIでも再現するサンプル:

fu! T(...)
  sleep 3
  call getchar(1)
endfu
call timer_start(0, 'T')

timer callback中のキー入力が滞留する。

Member

ichizok commented Aug 30, 2017

CUIでも再現するサンプル:

fu! T(...)
  sleep 3
  call getchar(1)
endfu
call timer_start(0, 'T')

timer callback中のキー入力が滞留する。

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