mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 9.0.0913: only change in current window triggers the WinScrolled event
Problem: Only a change in the current window triggers the WinScrolled event. Solution: Trigger WinScrolled if any window scrolled or changed size. (issue #11576)
This commit is contained in:
@@ -1372,16 +1372,32 @@ WinNew When a new window was created. Not done for
|
|||||||
|
|
||||||
*WinScrolled*
|
*WinScrolled*
|
||||||
WinScrolled After scrolling the content of a window or
|
WinScrolled After scrolling the content of a window or
|
||||||
resizing a window.
|
resizing a window in the current tab page.
|
||||||
The pattern is matched against the
|
|
||||||
|window-ID|. Both <amatch> and <afile> are
|
When more than one window scrolled or resized
|
||||||
set to the |window-ID|.
|
only one WinScrolled event is triggered. You
|
||||||
Non-recursive (the event cannot trigger
|
can use the `winlayout()` and `getwininfo()`
|
||||||
itself). However, if the command causes the
|
functions to see what changed.
|
||||||
window to scroll or change size another
|
|
||||||
|
The pattern is matched against the |window-ID|
|
||||||
|
of the first window that scrolled or resized.
|
||||||
|
Both <amatch> and <afile> are set to the
|
||||||
|
|window-ID|.
|
||||||
|
|
||||||
|
Only starts triggering after startup finished
|
||||||
|
and the first screen redraw was done.
|
||||||
|
|
||||||
|
Non-recursive: the event will not trigger
|
||||||
|
while executing commands for the WinScrolled
|
||||||
|
event. However, if the command causes a
|
||||||
|
window to scroll or change size, then another
|
||||||
WinScrolled event will be triggered later.
|
WinScrolled event will be triggered later.
|
||||||
|
|
||||||
Does not trigger when the command is added,
|
Does not trigger when the command is added,
|
||||||
only after the first scroll or resize.
|
only after the first scroll or resize.
|
||||||
|
*E1312*
|
||||||
|
It is not allowed to change the window layout
|
||||||
|
here (split, close or move windows).
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
6. Patterns *autocmd-patterns* *{aupat}*
|
6. Patterns *autocmd-patterns* *{aupat}*
|
||||||
|
@@ -1469,6 +1469,9 @@ main_loop(
|
|||||||
time_fd = NULL;
|
time_fd = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// After the first screen update may start triggering WinScrolled
|
||||||
|
// autocmd events. Store all the scroll positions and sizes now.
|
||||||
|
may_make_initial_scroll_size_snapshot();
|
||||||
}
|
}
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
if (need_mouse_correct)
|
if (need_mouse_correct)
|
||||||
|
@@ -18,6 +18,7 @@ void curwin_init(void);
|
|||||||
void close_windows(buf_T *buf, int keep_curwin);
|
void close_windows(buf_T *buf, int keep_curwin);
|
||||||
int one_window(void);
|
int one_window(void);
|
||||||
int win_close(win_T *win, int free_buf);
|
int win_close(win_T *win, int free_buf);
|
||||||
|
void may_make_initial_scroll_size_snapshot(void);
|
||||||
void may_trigger_winscrolled(void);
|
void may_trigger_winscrolled(void);
|
||||||
void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp);
|
void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp);
|
||||||
void win_free_all(void);
|
void win_free_all(void);
|
||||||
|
10
src/testdir/dumps/Test_winscrolled_once_only_1.dump
Normal file
10
src/testdir/dumps/Test_winscrolled_once_only_1.dump
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|a+0&#ffffff0@2| @26||+1&&>b+0&&@2| @25
|
||||||
|
|b@2| @26||+1&&|~+0#4040ff13&| @27
|
||||||
|
|~| @28||+1#0000000&|~+0#4040ff13&| @27
|
||||||
|
|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1|||~+0#4040ff13&| @27
|
||||||
|
|a+0#0000000&@2| @26||+1&&|~+0#4040ff13&| @27
|
||||||
|
|b+0#0000000&@2| @26||+1&&|~+0#4040ff13&| @27
|
||||||
|
|~| @28||+1#0000000&|~+0#4040ff13&| @27
|
||||||
|
|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @1|2|,|1| @7|B|o|t
|
||||||
|
|1+0&&| |1|0@2| |[|'|r|o|w|'|,| |[@1|'|c|o|l|'|,| |[@1|'|l|e|a|f|'|,| |1|0@1|2|]|,| |[|'|l|e|a|f|'|,| |1|0@1|1|]@2|,| |[
|
||||||
|
|'|l|e|a|f|'|,| |1|0@2|]@2| @44
|
@@ -407,11 +407,38 @@ func Test_WinScrolled_close_curwin()
|
|||||||
call TermWait(buf)
|
call TermWait(buf)
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
|
|
||||||
|
" check the startup script finished to the end
|
||||||
call assert_equal(['123456'], readfile('Xtestout'))
|
call assert_equal(['123456'], readfile('Xtestout'))
|
||||||
|
|
||||||
call delete('Xtestout')
|
call delete('Xtestout')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_WinScrolled_once_only()
|
||||||
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
set cmdheight=2
|
||||||
|
call setline(1, ['aaa', 'bbb'])
|
||||||
|
let trigger_count = 0
|
||||||
|
func ShowInfo(id)
|
||||||
|
echo g:trigger_count g:winid winlayout()
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
vsplit
|
||||||
|
split
|
||||||
|
" use a timer to show the info after a redraw
|
||||||
|
au WinScrolled * let trigger_count += 1 | let winid = expand('<amatch>') | call timer_start(100, 'ShowInfo')
|
||||||
|
wincmd j
|
||||||
|
wincmd l
|
||||||
|
END
|
||||||
|
call writefile(lines, 'Xtest_winscrolled_once', 'D')
|
||||||
|
let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "\<C-E>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_WinScrolled_long_wrapped()
|
func Test_WinScrolled_long_wrapped()
|
||||||
CheckRunVimInTerminal
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
@@ -2916,6 +2943,7 @@ func Test_SpellFileMissing_bwipe()
|
|||||||
call assert_fails('set spell spelllang=0', 'E937:')
|
call assert_fails('set spell spelllang=0', 'E937:')
|
||||||
|
|
||||||
au! SpellFileMissing
|
au! SpellFileMissing
|
||||||
|
set nospell spelllang=en
|
||||||
bwipe
|
bwipe
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
913,
|
||||||
/**/
|
/**/
|
||||||
912,
|
912,
|
||||||
/**/
|
/**/
|
||||||
|
88
src/window.c
88
src/window.c
@@ -2843,44 +2843,76 @@ trigger_winclosed(win_T *win)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trigger WinScrolled for "curwin" if needed.
|
* Make a snapshot of all the window scroll positions and sizes of the current
|
||||||
|
* tab page.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
snapshot_windows_scroll_size(void)
|
||||||
|
{
|
||||||
|
win_T *wp;
|
||||||
|
FOR_ALL_WINDOWS(wp)
|
||||||
|
{
|
||||||
|
wp->w_last_topline = wp->w_topline;
|
||||||
|
wp->w_last_leftcol = wp->w_leftcol;
|
||||||
|
wp->w_last_skipcol = wp->w_skipcol;
|
||||||
|
wp->w_last_width = wp->w_width;
|
||||||
|
wp->w_last_height = wp->w_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int did_initial_scroll_size_snapshot = FALSE;
|
||||||
|
|
||||||
|
void
|
||||||
|
may_make_initial_scroll_size_snapshot(void)
|
||||||
|
{
|
||||||
|
if (!did_initial_scroll_size_snapshot)
|
||||||
|
{
|
||||||
|
did_initial_scroll_size_snapshot = TRUE;
|
||||||
|
snapshot_windows_scroll_size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger WinScrolled if any window scrolled or changed size.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
may_trigger_winscrolled(void)
|
may_trigger_winscrolled(void)
|
||||||
{
|
{
|
||||||
static int recursive = FALSE;
|
static int recursive = FALSE;
|
||||||
|
|
||||||
if (recursive || !has_winscrolled())
|
if (recursive
|
||||||
|
|| !has_winscrolled()
|
||||||
|
|| !did_initial_scroll_size_snapshot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
win_T *wp = curwin;
|
win_T *wp;
|
||||||
if (wp->w_last_topline != wp->w_topline
|
FOR_ALL_WINDOWS(wp)
|
||||||
|| wp->w_last_leftcol != wp->w_leftcol
|
if (wp->w_last_topline != wp->w_topline
|
||||||
|| wp->w_last_skipcol != wp->w_skipcol
|
|| wp->w_last_leftcol != wp->w_leftcol
|
||||||
|| wp->w_last_width != wp->w_width
|
|| wp->w_last_skipcol != wp->w_skipcol
|
||||||
|| wp->w_last_height != wp->w_height)
|
|| wp->w_last_width != wp->w_width
|
||||||
{
|
|| wp->w_last_height != wp->w_height)
|
||||||
// "curwin" may be different from the actual current window, make sure
|
|
||||||
// it can be restored.
|
|
||||||
window_layout_lock();
|
|
||||||
|
|
||||||
recursive = TRUE;
|
|
||||||
char_u winid[NUMBUFLEN];
|
|
||||||
vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id);
|
|
||||||
apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer);
|
|
||||||
recursive = FALSE;
|
|
||||||
window_layout_unlock();
|
|
||||||
|
|
||||||
// an autocmd may close the window, "wp" may be invalid now
|
|
||||||
if (win_valid_any_tab(wp))
|
|
||||||
{
|
{
|
||||||
wp->w_last_topline = wp->w_topline;
|
// WinScrolled is triggered only once, even when multiple windows
|
||||||
wp->w_last_leftcol = wp->w_leftcol;
|
// scrolled or changed size. Store the current values before
|
||||||
wp->w_last_skipcol = wp->w_skipcol;
|
// triggering the event, if a scroll or resize happens as a side
|
||||||
wp->w_last_width = wp->w_width;
|
// effect then WinScrolled is triggered again later.
|
||||||
wp->w_last_height = wp->w_height;
|
snapshot_windows_scroll_size();
|
||||||
|
|
||||||
|
// "curwin" may be different from the actual current window, make
|
||||||
|
// sure it can be restored.
|
||||||
|
window_layout_lock();
|
||||||
|
|
||||||
|
recursive = TRUE;
|
||||||
|
char_u winid[NUMBUFLEN];
|
||||||
|
vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id);
|
||||||
|
apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE,
|
||||||
|
wp->w_buffer);
|
||||||
|
recursive = FALSE;
|
||||||
|
window_layout_unlock();
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user