]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0139: Cannot configure terminal resize event v9.2.0139
authorFoxe Chen <chen.foxe@gmail.com>
Wed, 11 Mar 2026 20:03:36 +0000 (20:03 +0000)
committerChristian Brabandt <cb@256bit.org>
Wed, 11 Mar 2026 20:03:36 +0000 (20:03 +0000)
Problem:  Cannot configure terminal resize event
Solution: Add the 'termresize' option and allow to use in-band window
          resize events (Foxe Chen).

closes: #19596

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
19 files changed:
runtime/doc/options.txt
runtime/doc/tags
runtime/doc/version9.txt
runtime/optwin.vim
runtime/syntax/vim.vim
src/gui.c
src/main.c
src/option.h
src/optiondefs.h
src/optionstr.c
src/os_unix.c
src/po/vim.pot
src/proto/optionstr.pro
src/proto/os_unix.pro
src/proto/term.pro
src/term.c
src/testdir/test_termcodes.vim
src/testdir/util/gen_opt_test.vim
src/version.c

index c7e010d59d43259ca33821e527bed5acaaf9699c..7131e7efa73f7429a1641a7c91d7072ec22acdcc 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 9.2.  Last change: 2026 Mar 04
+*options.txt*  For Vim version 9.2.  Last change: 2026 Mar 11
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -9096,6 +9096,24 @@ A jump table for the options with a short description can be found at |Q_op|.
 <
        NOTE: This option is reset when 'compatible' is set.
 
+                                               *'termresize* *'trz'*
+'termresize' 'trz'     number  (default "")
+                       global
+                       {only available in Unix, does not work in the GUI}
+       Determines the method to use for detecting window resize events,
+       possible values are:
+           "sigwinch":     Use the SIGWINCH signal.
+           "inband":       Receive resize events from the terminal via escape
+                           sequences (recommended if supported by terminal).
+           "":             Automatically choose depending on terminal.
+
+       The SIGWINCH handler is always available.  If set to "inband" and the
+       terminal does not support in-band window resize events, then the
+       SIGWINCH handler will be used instead as a fallback.  If set to ""
+       (empty option), then "inband" will be used if Vim detects that the
+       terminal supports it, otherwise "sigwinch".
+
+
                                                *'termsync'* *'tsy'*
 'termsync' 'tsy'       boolean (default off)
                        global
index a000eacbddc6d6fff6dd3853d88a4ebb31cbc9bf..4fe69bacefc6a9835a921e46723e692ee81c30f6 100644 (file)
@@ -1237,6 +1237,7 @@ $quote    eval.txt        /*$quote*
 'termbidi'     options.txt     /*'termbidi'*
 'termencoding' options.txt     /*'termencoding'*
 'termguicolors'        options.txt     /*'termguicolors'*
+'termresize    options.txt     /*'termresize*
 'termsync'     options.txt     /*'termsync'*
 'termwinkey'   options.txt     /*'termwinkey'*
 'termwinscroll'        options.txt     /*'termwinscroll'*
@@ -1269,6 +1270,7 @@ $quote    eval.txt        /*$quote*
 'tplo' options.txt     /*'tplo'*
 'tpm'  options.txt     /*'tpm'*
 'tr'   options.txt     /*'tr'*
+'trz'  options.txt     /*'trz'*
 'ts'   options.txt     /*'ts'*
 'tsl'  options.txt     /*'tsl'*
 'tsr'  options.txt     /*'tsr'*
index 5d122ef412b06c3a270e200fb7f86605cf527799..6bbb700e9ffd66edc04a0b384fd660ce2ec79d93 100644 (file)
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.2.  Last change: 2026 Mar 08
+*version9.txt* For Vim version 9.2.  Last change: 2026 Mar 11
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -52616,6 +52616,7 @@ Options: ~
                        "maxheight" suboption to use several lines.
 't_BS'                 Begin synchronized update.
 't_ES'                 End synchronized update.
+'termresize'           Method for handling terminal resize events.
 'termsync'             Enable support for terminal DEC 2026 sync mode.
 'winhighlight'         Window-local highlight group mappings.
 
index 7d30f010b1292c23267e124025672ecc16adb0c3..e20fda26b7c8fd927d5e3e8b5326be00809ea8b5 100644 (file)
@@ -1,7 +1,7 @@
 " These commands create the option window.
 "
 " Maintainer:  The Vim Project <https://github.com/vim/vim>
-" Last Change: 2026 Mar 04
+" Last Change: 2026 Mar 11
 " Former Maintainer:   Bram Moolenaar <Bram@vim.org>
 
 " If there already is an option window, jump to that one.
@@ -385,6 +385,10 @@ call <SID>AddOption("window", gettext("number of lines to scroll for CTRL-F and
 call append("$", " \tset window=" . &window)
 call <SID>AddOption("lazyredraw", gettext("don't redraw while executing macros"))
 call <SID>BinOptionG("lz", &lz)
+if has("unix")
+  call <SID>AddOption("termresize", gettext("configure method of receiving terminal size changes"))
+  call <SID>BinOptionG("trz", &trz)
+endif
 call <SID>AddOption("termsync", gettext("enable terminal sync mode"))
 call <SID>BinOptionG("tsy", &tsy)
 if has("reltime")
index 5caee0534794b459afd3fe8de370fa737b607613..dc0356eaeaf30d55531f210ec6368a5899494e98 100644 (file)
@@ -2,7 +2,7 @@
 " Language:       Vim script
 " Maintainer:     Hirohito Higashi <h.east.727 ATMARK gmail.com>
 "         Doug Kearns <dougkearns@gmail.com>
-" Last Change:    2026 Mar 04
+" Last Change:    2026 Mar 11
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -70,9 +70,9 @@ syn keyword vimOption contained efm errorformat ek esckeys ei eventignore eiw ev
 syn keyword vimOption contained hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lhi lhistory lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth skipwhite nextgroup=vimSetEqual,vimSetMod
 syn keyword vimOption contained mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot msc maxsearchcount mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc ost osctimeoutlen pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont skipwhite nextgroup=vimSetEqual,vimSetMod
 syn keyword vimOption contained popt printoptions prompt pb pumborder ph pumheight pmw pummaxwidth pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors tsy termsync skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors trz termresize skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained tsy termsync twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
 
 " vimOptions: These are the turn-off setting variants {{{2
 " GEN_SYN_VIM: vimOption turn-off, START_STR='syn keyword vimOption contained', END_STR=''
@@ -110,8 +110,8 @@ syn keyword vimOptionVarName contained hi history hk hkmap hkp hkmapp hls hlsear
 syn keyword vimOptionVarName contained mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot msc maxsearchcount mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc ost osctimeoutlen pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset
 syn keyword vimOptionVarName contained pmbfn printmbfont popt printoptions prompt pb pumborder ph pumheight pmw pummaxwidth pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess
 syn keyword vimOptionVarName contained sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding
-syn keyword vimOptionVarName contained tgc termguicolors tsy termsync twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions
-syn keyword vimOptionVarName contained wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes
+syn keyword vimOptionVarName contained tgc termguicolors trz termresize tsy termsync twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode
+syn keyword vimOptionVarName contained wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes
 " GEN_SYN_VIM: vimOption term output code variable, START_STR='syn keyword vimOptionVarName contained', END_STR=''
 syn keyword vimOptionVarName contained t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u t_xo t_BS t_ES
 syn keyword vimOptionVarName contained t_F1 t_F2 t_F3 t_F4 t_F5 t_F6 t_F7 t_F8 t_F9 t_k1 t_K1 t_k2 t_k3 t_K3 t_k4 t_K4 t_k5 t_K5 t_k6 t_K6 t_k7 t_K7 t_k8 t_K8 t_k9 t_K9 t_KA t_kb t_kB t_KB t_KC t_kd t_kD t_KD t_KE t_KF t_KG t_kh t_KH t_kI t_KI t_KJ t_KK t_kl t_KL t_kN t_kP t_kr t_ku
index edf64368f99dac3c143a70daa5f700f32a8ad0a6..4238b8b731ba8f12caccbf8ef0358844d938ed94 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -78,6 +78,9 @@ gui_start(char_u *arg UNUSED)
        cursor_on();                    // needed for ":gui" in .vimrc
     full_screen = FALSE;
 
+    // If GUI fails to start, then we will recover afterwards
+    term_disable_dec();
+
 #ifdef GUI_MAY_FORK
     ++recursive;
     /*
@@ -141,6 +144,9 @@ gui_start(char_u *arg UNUSED)
        termcapinit(old_term);
        settmode(TMODE_RAW);            // restart RAW mode
        set_title_defaults();           // set 'title' and 'icon' again
+#ifdef UNIX
+       term_set_win_resize(true);
+#endif
 #if defined(GUI_MAY_SPAWN) && defined(EXPERIMENTAL_GUI_CMD)
        if (msg != NULL)
            emsg(msg);
@@ -148,11 +154,8 @@ gui_start(char_u *arg UNUSED)
     }
 #ifdef HAVE_CLIPMETHOD
     else
-    {
        // Reset clipmethod to CLIPMETHOD_NONE
        choose_clipmethod();
-       term_set_sync_output(TERM_SYNC_OUTPUT_OFF);
-    }
 #endif
 
 #if defined(FEAT_SOCKETSERVER) && defined(FEAT_GUI_GTK)
index 10828933de76656f7aa16c9627d354b65427abf9..4579690e121348ff380c6ad06e23305d9a3649dc 100644 (file)
@@ -893,7 +893,7 @@ vim_main2(void)
 
     may_req_bg_color();
 
-    may_req_sync_output();
+    may_req_dec_setting();
 # endif
 
     // start in insert mode
@@ -1857,7 +1857,7 @@ getout(int exitval)
     free_cmd_argsW();
 #endif
 
-    term_set_sync_output(TERM_SYNC_OUTPUT_OFF);
+    term_disable_dec();
 
     mch_exit(exitval);
 }
index 5f656f9b1a0c3389dd5e0706623e2ca0a4a4d511..966b0bdea648ce65542f9588d83205f0e5d26b16 100644 (file)
@@ -1035,6 +1035,9 @@ EXTERN char_u     *p_tenc;        // 'termencoding'
 #ifdef FEAT_TERMGUICOLORS
 EXTERN int     p_tgc;          // 'termguicolors'
 #endif
+#ifdef UNIX
+EXTERN char_u  *p_trz;         // 'termresize'
+#endif
 EXTERN int     p_tsy;          // 'termsync'
 #ifdef FEAT_TERMINAL
 EXTERN long    p_twsl;         // 'termwinscroll'
index 6ab34ff9e9f283e99a9c10834f634d72fbb36af3..d89b12523697b46b31a75099aef0dc778a5ebaf9 100644 (file)
@@ -2659,6 +2659,15 @@ static struct vimoption options[] =
 #else
                            (char_u*)NULL, PV_NONE, NULL, NULL,
                            {(char_u *)FALSE, (char_u *)FALSE}
+#endif
+                           SCTX_INIT},
+    {"termresize", "trz", P_STRING|P_VI_DEF,
+#ifdef UNIX
+                           (char_u *)&p_trz, PV_NONE, did_set_termresize, expand_set_termresize,
+                           {(char_u *)"", (char_u *)0}
+#else
+                           (char_u *)NULL, PV_NONE, NULL, NULL,
+                           {(char_u *)NULL, (char_u *)0L}
 #endif
                            SCTX_INIT},
     {"termsync", "tsy",            P_BOOL|P_VI_DEF,
index b94824d45c8539e178289fc820fb0898952e455f..aefb78ee8c87c826720c79bbe604acf4e0d5ebd4 100644 (file)
@@ -150,6 +150,9 @@ static char *(p_csl_values[]) = {"slash", "backslash", NULL};
 #ifdef FEAT_SIGNS
 static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
 #endif
+#ifdef UNIX
+static char *(p_trz_values[]) = {"inband", "sigwinch", "", NULL};
+#endif
 #if defined(MSWIN) && defined(FEAT_TERMINAL)
 static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL};
 #endif
@@ -4465,6 +4468,37 @@ did_set_term_option(optset_T *args)
     return NULL;
 }
 
+
+#ifdef UNIX
+/*
+ * The 'termresize' option is changed.
+ */
+    char *
+did_set_termresize(optset_T *args UNUSED)
+{
+    // If empty or "inband", then attempt to enable in-band resize events.
+    if (*p_trz == NUL || STRCMP(p_trz, "inband") == 0)
+       term_set_win_resize(true);
+    else if (STRCMP(p_trz, "sigwinch") == 0)
+       term_set_win_resize(false);
+    else
+       return e_invalid_argument;
+
+    return NULL;
+}
+
+    int
+expand_set_termresize(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+    return expand_set_opt_string(
+           args,
+           p_trz_values,
+           ARRAY_LENGTH(p_trz_values) - 1,
+           numMatches,
+           matches);
+}
+#endif
+
 #if defined(FEAT_TERMINAL)
 /*
  * The 'termwinkey' option is changed.
index 3bd2942cae795690e7bc29516c51c05cef286b4e..03f7649090c965d8edfcc610c0f00f67ef64a3a5 100644 (file)
@@ -1568,6 +1568,14 @@ mch_init(void)
 #ifdef FEAT_CYGWIN_WIN32_CLIPBOARD
     win_clip_init();
 #endif
+}
+
+    void
+set_sigwinch_handler(void)
+{
+#if defined(SIGWINCH)
+    mch_signal(SIGWINCH, sig_winch);
+#endif
 }
 
     static void
index 32898088cd788afa30d4b1c8154434a17ffbb87b..c9d9a0aa8effb0eb412a027fe67e4381e30405c1 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim\n"
 "Report-Msgid-Bugs-To: vim-dev@vim.org\n"
-"POT-Creation-Date: 2026-03-04 21:06+0000\n"
+"POT-Creation-Date: 2026-03-11 20:02+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -9445,6 +9445,9 @@ msgstr ""
 msgid "don't redraw while executing macros"
 msgstr ""
 
+msgid "configure method of receiving terminal size changes"
+msgstr ""
+
 msgid "enable terminal sync mode"
 msgstr ""
 
index e4e39e759cd27bda8a658ca379951b45b9865cae..be8b8e97b52ba112ca69810daa90b32c79567483 100644 (file)
@@ -180,6 +180,8 @@ char *did_set_tagcase(optset_T *args);
 int expand_set_tagcase(optexpand_T *args, int *numMatches, char_u ***matches);
 char *did_set_term(optset_T *args);
 char *did_set_term_option(optset_T *args);
+char *did_set_termresize(optset_T *args);
+int expand_set_termresize(optexpand_T *args, int *numMatches, char_u ***matches);
 char *did_set_termwinkey(optset_T *args);
 char *did_set_termwinsize(optset_T *args);
 char *did_set_termwintype(optset_T *args);
index 41efd0f2cb42c2ac08d632a5cdb598c172538a1c..5abaae6216bdf400cc24765344b146b5b4c0d4c0 100644 (file)
@@ -10,6 +10,7 @@ void mch_delay(long msec, int flags);
 int mch_stackcheck(char *p);
 void mch_suspend(void);
 void mch_init(void);
+void set_sigwinch_handler(void);
 void reset_signals(void);
 int vim_handle_signal(int sig);
 int mch_check_win(int argc, char **argv);
index 862864b399851c75f346e30ec474692a4fa25b37..80f9b00e930732aa610af267e6e7e969746486a3 100644 (file)
@@ -96,6 +96,8 @@ void swap_tcap(void);
 void ansi_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx);
 void cterm_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx);
 int term_replace_keycodes(char_u *ta_buf, int ta_len, int len_arg);
-void may_req_sync_output(void);
+void may_req_dec_setting(void);
+void term_disable_dec(void);
+void term_set_win_resize(bool state);
 void term_set_sync_output(int flags);
 /* vim: set ft=c : */
index 5c3212b269edfb84979c292bd5faab2b920ec0c9..21c529db97b266544f33ce4758f0d35790d6224b 100644 (file)
@@ -133,6 +133,11 @@ static termrequest_T xcc_status = TERMREQUEST_INIT;
 // Request synchronized output report
 static termrequest_T sync_output_status = TERMREQUEST_INIT;
 
+#ifdef UNIX
+// Request in-band window resize events report
+static termrequest_T win_resize_status = TERMREQUEST_INIT;
+#endif
+
 #ifdef FEAT_TERMRESPONSE
 # ifdef FEAT_TERMINAL
 // Request foreground color report:
@@ -169,6 +174,9 @@ static termrequest_T *all_termrequests[] = {
     &rcs_status,
     &winpos_status,
     &sync_output_status,
+# ifdef UNIX
+    &win_resize_status,
+# endif
     NULL
 };
 
@@ -246,6 +254,13 @@ static int sync_output_setting = 0;
 // == 0: No synchronized output
 static int sync_output_state = 0;
 
+#ifdef UNIX
+// DEC mode 2048 (in-band window resize events)
+// https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
+static int win_resize_setting = 0;
+static bool win_resize_enabled = false;
+#endif
+
 /*
  * The builtin termcap entries.
  *
@@ -5594,7 +5609,7 @@ handle_csi_function_key(
  *
  * - DA1 query response: {lead}?...;c
  *
- * - DEC mode 2026 response (synchronized output): {lead}?2026;{mode}$y
+ * - DECRPM response: {lead}?2026;{mode}$y
  *
  * Return 0 for no match, -1 for partial match, > 0 for full match.
  */
@@ -5724,8 +5739,9 @@ handle_csi(
        key_name[1] = (int)KE_IGNORE;
     }
 
-    // DEC 2026 mode response (for 'termsync' option)
-    else if (first == '?' && trail == 'y' && argc == 2 && arg[0] == 2026)
+    // DECRPM mode 2026 or 2048.
+    else if (first == '?' && trail == 'y' && argc == 2
+           && (arg[0] == 2026 || arg[0] == 2048))
     {
        int setting = arg[1];
 
@@ -5735,16 +5751,43 @@ handle_csi(
 
        if (setting >= 0 && setting <= 4)
        {
-           sync_output_setting = setting;
-           LOG_TRN("Received DEC 2026 mode: %s", tp);
-           sync_output_status.tr_progress = STATUS_GOT;
+           LOG_TRN("Received DECRPM mode %d: %s", arg[0], tp);
+
+           switch (arg[0])
+           {
+               case 2026:
+                   sync_output_setting = setting;
+                   sync_output_status.tr_progress = STATUS_GOT;
+                   set_option_value_give_err((char_u *)"termsync",
+                           setting == 1 || setting == 2, NULL, 0);
+                   break;
+#ifdef UNIX
+               case 2048:
+                   win_resize_status.tr_progress = STATUS_GOT;
+                   win_resize_setting = setting;
 
-           set_option_value_give_err((char_u *)"termsync",
-                   setting == 1 || setting == 2, NULL, 0);
+                   term_set_win_resize(true);
+                   break;
+#endif
+           }
        }
        else
-           LOG_TRN("Unknown synchronized output setting %d", setting);
+           LOG_TRN("Unknown DECRPM mode %d setting %d", arg[0], setting);
+    }
+
+#ifdef UNIX
+    // In-band window resize event
+    else if (win_resize_enabled && argc >= 3 && arg[0] == 48)
+    {
+       int height = arg[1], width = arg[2];
+
+       *slen = csi_len;
+       key_name[0] = (int)KS_EXTRA;
+       key_name[1] = (int)KE_IGNORE;
+
+       set_shellsize(width, height, true);
     }
+#endif
 
     // Version string: Eat it when there is at least one digit and
     // it ends in 'c'
@@ -7855,26 +7898,107 @@ term_replace_keycodes(char_u *ta_buf, int ta_len, int len_arg)
 
 #ifdef FEAT_TERMRESPONSE
 /*
- * Query the setting for DEC mode 2026 (synchronized output) from the terminal.
+ * Query the setting for the following DEC modes from the terminal:
+ * - DEC mode 2026 (synchronized output)
+ * - DEC mode 2048 (window resize events)
  */
     void
-may_req_sync_output(void)
+may_req_dec_setting(void)
 {
-    if (can_get_termresponse() && starting == 0
-           && sync_output_status.tr_progress == STATUS_GET)
+    if (can_get_termresponse() && starting == 0)
     {
-       MAY_WANT_TO_LOG_THIS;
-       LOG_TR1("Sending synchronized output request");
+       bool didit = false;
 
-       out_str((char_u *)"\033[?2026$p");
-       termrequest_sent(&sync_output_status);
+       if (sync_output_status.tr_progress == STATUS_GET)
+       {
+           MAY_WANT_TO_LOG_THIS;
+           LOG_TR1("Sending synchronized output request");
 
-       // check for the characters now, otherwise they might be eaten by
-       // get_keystroke()
-       out_flush();
-       (void)vpeekc_nomap();
+           out_str((char_u *)"\033[?2026$p");
+           termrequest_sent(&sync_output_status);
+           didit = true;
+       }
+
+# ifdef UNIX
+       if (win_resize_status.tr_progress == STATUS_GET)
+       {
+           MAY_WANT_TO_LOG_THIS;
+           LOG_TR1("Sending in-band window resize events request");
+
+           out_str((char_u *)"\033[?2048$p");
+           termrequest_sent(&win_resize_status);
+           didit = true;
+       }
+# endif
+
+       if (didit)
+       {
+           // check for the characters now, otherwise they might be eaten by
+           // get_keystroke()
+           out_flush();
+           (void)vpeekc_nomap();
+       }
     }
+}
+#endif
+
+/*
+ * Should be called when cleaning up terminal state.
+ */
+    void
+term_disable_dec(void)
+{
+    term_set_sync_output(TERM_SYNC_OUTPUT_OFF);
+#ifdef UNIX
+    term_set_win_resize(false);
+#endif
+    // Make sure to always flush the output buffer, because this may be called
+    // before starting the GUI
+    out_flush();
+}
 
+#ifdef UNIX
+/*
+ * Enable or disable receiving in-band window resize events from the terminal.
+ * If "state" is true, then if the terminal supports DEC mode 2048 and
+ * 'termresize' is "" or "inband", then enable it and disable the SIGWINCH
+ * signal handling. Otherwise disable the mode if it is enabled and reinstall
+ * the SIGWINCH handler.
+ */
+    void
+term_set_win_resize(bool state)
+{
+# ifdef FEAT_GUI
+    bool    in_gui = gui.in_use;
+# else
+    bool    in_gui = false;
+# endif
+
+    if (state && in_gui)
+       return;
+
+    if (!state || win_resize_setting == 0 || win_resize_setting == 4)
+    {
+       // Make sure it update internal window size if DEC mode 2048 is
+       // unavailable now.
+       if (win_resize_enabled)
+       {
+           set_shellsize(0, 0, false);
+           set_sigwinch_handler();
+           out_str((char_u *)"\033[?2048l");
+       }
+       win_resize_enabled = false;
+    }
+    else if ((*p_trz == NUL || STRCMP(p_trz, "inband") == 0)
+           && !win_resize_enabled)
+    {
+       if (win_resize_setting == 2)
+           out_str((char_u *)"\033[?2048h");
+# ifdef SIGWINCH
+       mch_signal(SIGWINCH, SIG_DFL);
+# endif
+       win_resize_enabled = true;
+    }
 }
 #endif
 
index 43c75693e01584e36f3658a1b3a832c4d3dd8a50..e5f31259e516acd4087fba12b7b2ffe097a6ed86 100644 (file)
@@ -2966,4 +2966,73 @@ func Test_term_rgb_response()
   set t_RF= t_RB=
 endfunc
 
+" Test in-band window resize events (DEC mode 2048).
+" https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
+func Test_term_win_resize()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+  vim9script
+
+  autocmd VimResized * writefile([$"{&lines} {&columns}"], "XTestWinResizeResult")
+  END
+  call writefile(lines, 'XTestWinResize', 'D')
+  defer delete("XTestWinResizeResult")
+
+  let buf = RunVimInTerminal('-S XTestWinResize', #{rows: 15, cols: 20})
+
+  " Send status report
+  call term_sendkeys(buf, "\<Esc>[?2048;1$y")
+  call TermWait(buf)
+
+  " Resize to 50 rows 100 cols
+  call term_sendkeys(buf, "\<Esc>[48;50;100;0;0t")
+  call TermWait(buf)
+
+  call WaitForAssert({-> assert_equal(["50 100"], readfile("XTestWinResizeResult"))})
+
+  " SIGWINCH handler should be uninstalled
+  call job_stop(term_getjob(buf), 28)
+  call TermWait(buf)
+
+  call WaitForAssert({-> assert_equal(["50 100"], readfile("XTestWinResizeResult"))})
+
+  " SIGWINCH handler should be reinstalled again
+  call term_sendkeys(buf, "\<Esc>:set termresize=sigwinch\<CR>")
+  call TermWait(buf)
+
+  call WaitForAssert({-> assert_equal(["15 20"], readfile("XTestWinResizeResult"))})
+
+  call term_sendkeys(buf, "\<Esc>:set termresize=\<CR>")
+  call TermWait(buf)
+
+  call term_sendkeys(buf, "\<Esc>[48;50;30;0;0t")
+  call TermWait(buf)
+
+  call WaitForAssert({-> assert_equal(["50 30"], readfile("XTestWinResizeResult"))})
+
+  " Simulate no support for in-band window resize
+  call term_sendkeys(buf, "\<Esc>[?2048;0$y")
+  call TermWait(buf)
+
+  " Should reinstall SIGWINCH handler
+  call WaitForAssert({-> assert_equal(["15 20"], readfile("XTestWinResizeResult"))})
+
+  call term_setsize(buf, 5, 20)
+  call TermWait(buf)
+  call WaitForAssert({-> assert_equal(["5 20"], readfile("XTestWinResizeResult"))})
+
+  " Setting 'termresize' to "inband" should do nothing if support is not
+  " detected from terminal.
+  call term_sendkeys(buf, "\<Esc>:set termresize=inband\<CR>")
+  call TermWait(buf)
+
+  call term_sendkeys(buf, "\<Esc>[48;50;100;0;0t")
+  call TermWait(buf)
+
+  call WaitForAssert({-> assert_equal(["5 20"], readfile("XTestWinResizeResult"))})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index e1476001f3fff50215031da111f0b318a6f7aa8a..c2c5191daa3dfc0e21fdf048ae02d29d9bf72964 100644 (file)
@@ -389,6 +389,13 @@ if !has('clipboard')
        \ ]
 endif
 
+if has('unix')
+  let test_values['termresize'] = [
+       \ ['', 'sigwinch', 'inband'],
+       \ ['xxx', 'sig']
+       \ ]
+endif
+
 " Two lists with values: values that pre- and post-processing in test.
 " Clear out t_WS: we don't want to resize the actual terminal.
 let test_prepost = {
index 028abc2f084c07543b1e67430d3e2fce50b6f0a5..ad7d6ab32fe2b9ad6b86f32cd65b65ade0c1a597 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    139,
 /**/
     138,
 /**/