From c947b9ae419114ebfef9725814ea41a466fcf879 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 6 Apr 2022 17:59:21 +0100 Subject: [PATCH 01/11] patch 8.2.4700: buffer remains active if WinClosed event throws an exception Problem: Buffer remains active if a WinClosed event throws an exception. Solution: Ignore aborting() when closing the buffer. (closes #10097) --- src/testdir/test_autocmd.vim | 17 +++++++++++++++++ src/version.c | 2 ++ src/window.c | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 39ba9af7dc..89023a1fb7 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -348,6 +348,23 @@ func Test_WinClosed() unlet g:triggered endfunc +func Test_WinClosed_throws() + vnew + let bnr = bufnr() + call assert_equal(1, bufloaded(bnr)) + augroup test-WinClosed + autocmd WinClosed * throw 'foo' + augroup END + try + close + catch /.*/ + endtry + call assert_equal(0, bufloaded(bnr)) + + autocmd! test-WinClosed + augroup! test-WinClosed +endfunc + func s:AddAnAutocmd() augroup vimBarTest au BufReadCmd * echo 'hello' diff --git a/src/version.c b/src/version.c index 120633f0fa..6900961a99 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4700, /**/ 4699, /**/ diff --git a/src/window.c b/src/window.c index 30fa80292d..8ec4823a98 100644 --- a/src/window.c +++ b/src/window.c @@ -2493,7 +2493,7 @@ win_close_buffer(win_T *win, int action, int abort_if_last) set_bufref(&bufref, curbuf); win->w_closing = TRUE; - close_buffer(win, win->w_buffer, action, abort_if_last, FALSE); + close_buffer(win, win->w_buffer, action, abort_if_last, TRUE); if (win_valid_any_tab(win)) win->w_closing = FALSE; // Make sure curbuf is valid. It can become invalid if 'bufhidden' is From 3ad2090316edc85e93094bba7af64f9991cc7f85 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 6 Apr 2022 18:57:39 +0100 Subject: [PATCH 02/11] patch 8.2.4701: Kuka Robot Language files not recognized Problem: Kuka Robot Language files not recognized. Solution: Recognize *.src and *.dat files. (Patrick Meiser-Knosowski, closes #10096) --- runtime/autoload/dist/ft.vim | 17 ++++++++++++ runtime/filetype.vim | 5 ++++ src/testdir/test_filetype.vim | 49 +++++++++++++++++++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 73 insertions(+) diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim index a36f615d61..fd14062356 100644 --- a/runtime/autoload/dist/ft.vim +++ b/runtime/autoload/dist/ft.vim @@ -896,6 +896,23 @@ export def FTtf() setf tf enddef +# Determine if a *.src file is Kuka Robot Language +export def FTsrc() + if exists("g:filetype_src") + exe "setf " .. g:filetype_src + elseif getline(nextnonblank(1)) =~? '^\s*\%(&\w\+\|\%(global\s\+\)\?def\>\)' + setf krl + endif +enddef + +# Determine if a *.dat file is Kuka Robot Language +export def FTdat() + if exists("g:filetype_dat") + exe "setf " .. g:filetype_dat + elseif getline(nextnonblank(1)) =~? '^\s*\%(&\w\+\|defdat\>\)' + setf krl + endif +enddef # Uncomment this line to check for compilation errors early # defcompile diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 7aeed626a9..9d63a7fe89 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -951,6 +951,11 @@ au BufNewFile,BufRead *.jl setf julia " Kixtart au BufNewFile,BufRead *.kix setf kix +" Kuka Robot Language +au BufNewFile,BufRead *.src\c call dist#ft#FTsrc() +au BufNewFile,BufRead *.dat\c call dist#ft#FTdat() +au BufNewFile,BufRead *.sub\c setf krl + " Kimwitu[++] au BufNewFile,BufRead *.k setf kwt diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index 4f0dbd7d6f..dc2dc5ae4e 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -290,6 +290,7 @@ let s:filename_checks = { \ 'kivy': ['file.kv'], \ 'kix': ['file.kix'], \ 'kotlin': ['file.kt', 'file.ktm', 'file.kts'], + \ 'krl': ['file.sub', 'file.Sub', 'file.SUB'], \ 'kscript': ['file.ks'], \ 'kwt': ['file.k'], \ 'lace': ['file.ace', 'file.ACE'], @@ -869,6 +870,30 @@ func Test_d_file() call delete('Xfile.d') endfunc +func Test_dat_file() + filetype on + + call writefile(['&ACCESS'], 'datfile.dat') + split datfile.dat + call assert_equal('krl', &filetype) + bwipe! + call delete('datfile.dat') + + call writefile([' DEFDAT datfile'], 'datfile.Dat') + split datfile.Dat + call assert_equal('krl', &filetype) + bwipe! + call delete('datfile.Dat') + + call writefile(['', 'defdat datfile'], 'datfile.DAT') + split datfile.DAT + call assert_equal('krl', &filetype) + bwipe! + call delete('datfile.DAT') + + filetype off +endfunc + func Test_dep3patch_file() filetype on @@ -1311,6 +1336,30 @@ func Test_pp_file() filetype off endfunc +func Test_src_file() + filetype on + + call writefile(['&ACCESS'], 'srcfile.src') + split srcfile.src + call assert_equal('krl', &filetype) + bwipe! + call delete('srcfile.src') + + call writefile([' DEF srcfile()'], 'srcfile.Src') + split srcfile.Src + call assert_equal('krl', &filetype) + bwipe! + call delete('srcfile.Src') + + call writefile(['', 'global def srcfile()'], 'srcfile.SRC') + split srcfile.SRC + call assert_equal('krl', &filetype) + bwipe! + call delete('srcfile.SRC') + + filetype off +endfunc + func Test_tex_file() filetype on diff --git a/src/version.c b/src/version.c index 6900961a99..f00fbcb27b 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4701, /**/ 4700, /**/ From 3506cf34c17c5eae6c2d1317db1fcd5a8493c288 Mon Sep 17 00:00:00 2001 From: Tom Praschan <13141438+tom-anders@users.noreply.github.com> Date: Thu, 7 Apr 2022 12:39:08 +0100 Subject: [PATCH 03/11] patch 8.2.4702: C++ scope labels are hard-coded Problem: C++ scope labels are hard-coded. Solution: Add 'cinscopedecls' to define the labels. (Rom Praschan, closes #10109) --- runtime/doc/indent.txt | 8 ++++--- runtime/doc/options.txt | 14 ++++++++++-- runtime/doc/quickref.txt | 1 + runtime/optwin.vim | 5 +++++ src/buffer.c | 1 + src/cindent.c | 38 +++++++++++++++++++++---------- src/option.c | 3 +++ src/option.h | 2 ++ src/optiondefs.h | 10 +++++++++ src/optionstr.c | 1 + src/structs.h | 1 + src/testdir/test_cindent.vim | 43 ++++++++++++++++++++++++++++++++++++ src/version.c | 2 ++ 13 files changed, 112 insertions(+), 17 deletions(-) diff --git a/runtime/doc/indent.txt b/runtime/doc/indent.txt index 6e8f35b2d2..69a03f977d 100644 --- a/runtime/doc/indent.txt +++ b/runtime/doc/indent.txt @@ -42,11 +42,12 @@ is not a C compiler: it does not recognize all syntax. One requirement is that toplevel functions have a '{' in the first column. Otherwise they are easily confused with declarations. -These four options control C program indenting: +These five options control C program indenting: 'cindent' Enables Vim to perform C program indenting automatically. 'cinkeys' Specifies which keys trigger reindenting in insert mode. 'cinoptions' Sets your preferred indent style. 'cinwords' Defines keywords that start an extra indent in the next line. +'cinscopedecls' Defines strings that are recognized as a C++ scope declaration. If 'lisp' is not on and 'equalprg' is empty, the "=" operator indents using Vim's built-in algorithm rather than calling an external program. @@ -293,8 +294,9 @@ The examples below assume a 'shiftwidth' of 4. < *cino-g* gN Place C++ scope declarations N characters from the indent of the - block they are in. (default 'shiftwidth'). A scope declaration - can be "public:", "protected:" or "private:". + block they are in. (default 'shiftwidth'). By default, a scope + declaration is "public:", "protected:" or "private:". This can + be adjusted with the 'cinscopedecls' option. cino= cino=g0 > { { diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index d5e5e6834d..8b2021107b 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1661,13 +1661,23 @@ A jump table for the options with a short description can be found at |Q_op|. matter, include the keyword both the uppercase and lowercase: "if,If,IF". - *'clipboard'* *'cb'* + *'cinscopedecls'* *'cinsd'* +'cinscopedecls' 'cinsd' string (default "public,protected,private") + local to buffer + {not available when compiled without the |+cindent| + feature} + Keywords that are interpreted as a C++ scope declaration by |cino-g|. + Useful e.g. for working with the Qt framework that defines additional + scope declarations "signals", "public slots" and "private slots": > + set cinscopedecls+=signals,public\ slots,private\ slots + +< *'clipboard'* *'cb'* 'clipboard' 'cb' string (default "autoselect,exclude:cons\|linux" for X-windows, "" otherwise) global {only in GUI versions or when the |+xterm_clipboard| feature is included} - This option is a list of comma separated names. + This option is a list of comma-separated names. Note: if one of the items is "exclude:", then you can't add an item after that. Therefore do append an item with += but use ^= to prepend, e.g.: > diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index e532942914..279e3d56cc 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -643,6 +643,7 @@ Short explanation of each option: *option-list* 'cinkeys' 'cink' keys that trigger indent when 'cindent' is set 'cinoptions' 'cino' how to do indenting when 'cindent' is set 'cinwords' 'cinw' words where 'si' and 'cin' add an indent +'cinscopedecls' 'cinsd' words that are recognized by 'cino-g' 'clipboard' 'cb' use the clipboard as the unnamed register 'cmdheight' 'ch' number of lines to use for the command-line 'cmdwinheight' 'cwh' height of the command-line window diff --git a/runtime/optwin.vim b/runtime/optwin.vim index d138ab1d17..9b4868f7cf 100644 --- a/runtime/optwin.vim +++ b/runtime/optwin.vim @@ -624,6 +624,8 @@ call BinOptionG("scf", &scf) if has("gui") call AddOption("mousehide", gettext("hide the mouse pointer while typing")) call BinOptionG("mh", &mh) + call AddOption("mousemoveevent", gettext("report mouse movement events")) + call BinOptionG("mousemev", &mousemev) endif call AddOption("mousemodel", gettext("\"extend\", \"popup\" or \"popup_setpos\"; what the right\nmouse button is used for")) call OptionG("mousem", &mousem) @@ -927,6 +929,9 @@ if has("cindent") call AddOption("cinwords", gettext("list of words that cause more C-indent")) call append("$", "\t" .. s:local_to_buffer) call OptionL("cinw") + call AddOption("cinscopedecls", gettext("list of scope declaration names used by cino-g")) + call append("$", "\t" .. s:local_to_buffer) + call OptionL("cinsd") call AddOption("indentexpr", gettext("expression used to obtain the indent of a line")) call append("$", "\t" .. s:local_to_buffer) call OptionL("inde") diff --git a/src/buffer.c b/src/buffer.c index bd378302cd..5f8b1ad1dc 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2353,6 +2353,7 @@ free_buf_options( #ifdef FEAT_CINDENT clear_string_option(&buf->b_p_cink); clear_string_option(&buf->b_p_cino); + clear_string_option(&buf->b_p_cinsd); #endif #if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT) clear_string_option(&buf->b_p_cinw); diff --git a/src/cindent.c b/src/cindent.c index ca21c123e0..a22db9560e 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -423,20 +423,34 @@ cin_islabel_skip(char_u **s) * Recognize a "public/private/protected" scope declaration label. */ static int -cin_isscopedecl(char_u *s) +cin_isscopedecl(char_u *p) { - int i; + size_t cinsd_len; + char_u *cinsd_buf; + char_u *cinsd; + size_t len; + char_u *skip; + char_u *s = cin_skipcomment(p); - s = cin_skipcomment(s); - if (STRNCMP(s, "public", 6) == 0) - i = 6; - else if (STRNCMP(s, "protected", 9) == 0) - i = 9; - else if (STRNCMP(s, "private", 7) == 0) - i = 7; - else - return FALSE; - return (*(s = cin_skipcomment(s + i)) == ':' && s[1] != ':'); + cinsd_len = STRLEN(curbuf->b_p_cinsd) + 1; + cinsd_buf = alloc(cinsd_len); + if (cinsd_buf != NULL) + { + for (cinsd = curbuf->b_p_cinsd; *cinsd; ) + { + len = copy_option_part(&cinsd, cinsd_buf, cinsd_len, ","); + if (STRNCMP(s, cinsd_buf, len) == 0) + { + skip = cin_skipcomment(s + len); + if (*skip == ':' && skip[1] != ':') + return TRUE; + } + } + + vim_free(cinsd_buf); + } + + return FALSE; } /* diff --git a/src/option.c b/src/option.c index 4d50a6480c..49123aa36b 100644 --- a/src/option.c +++ b/src/option.c @@ -5449,6 +5449,7 @@ get_varp(struct vimoption *p) case PV_CIN: return (char_u *)&(curbuf->b_p_cin); case PV_CINK: return (char_u *)&(curbuf->b_p_cink); case PV_CINO: return (char_u *)&(curbuf->b_p_cino); + case PV_CINSD: return (char_u *)&(curbuf->b_p_cinsd); #endif #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) case PV_CINW: return (char_u *)&(curbuf->b_p_cinw); @@ -6020,6 +6021,8 @@ buf_copy_options(buf_T *buf, int flags) COPY_OPT_SCTX(buf, BV_CINK); buf->b_p_cino = vim_strsave(p_cino); COPY_OPT_SCTX(buf, BV_CINO); + buf->b_p_cinsd = vim_strsave(p_cinsd); + COPY_OPT_SCTX(buf, BV_CINSD); #endif // Don't copy 'filetype', it must be detected buf->b_p_ft = empty_option; diff --git a/src/option.h b/src/option.h index 85f2fa816f..4c583a48ff 100644 --- a/src/option.h +++ b/src/option.h @@ -400,6 +400,7 @@ EXTERN int p_bl; // 'buflisted' #ifdef FEAT_CINDENT EXTERN int p_cin; // 'cindent' EXTERN char_u *p_cink; // 'cinkeys' +EXTERN char_u *p_cinsd; // 'cinscopedecls' #endif #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) EXTERN char_u *p_cinw; // 'cinwords' @@ -1126,6 +1127,7 @@ enum , BV_CIN , BV_CINK , BV_CINO + , BV_CINSD #endif #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) , BV_CINW diff --git a/src/optiondefs.h b/src/optiondefs.h index 4f2ec4ddc5..54cccf83eb 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -44,6 +44,7 @@ # define PV_CIN OPT_BUF(BV_CIN) # define PV_CINK OPT_BUF(BV_CINK) # define PV_CINO OPT_BUF(BV_CINO) +# define PV_CINSD OPT_BUF(BV_CINSD) #endif #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) # define PV_CINW OPT_BUF(BV_CINW) @@ -603,6 +604,15 @@ static struct vimoption options[] = (char_u *)NULL, PV_NONE, #endif {(char_u *)"", (char_u *)0L} SCTX_INIT}, + {"cinscopedecls", "cinsd", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, +#ifdef FEAT_CINDENT + (char_u *)&p_cinsd, PV_CINSD, + {(char_u *)"public,protected,private", (char_u *)0L} +#else + (char_u *)NULL, PV_NONE, + {(char_u *)0L, (char_u *)0L} +#endif + SCTX_INIT}, {"cinwords", "cinw", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP, #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) (char_u *)&p_cinw, PV_CINW, diff --git a/src/optionstr.c b/src/optionstr.c index 09e6d8a12e..fd72da4df6 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -260,6 +260,7 @@ check_buf_options(buf_T *buf) #ifdef FEAT_CINDENT check_string_option(&buf->b_p_cink); check_string_option(&buf->b_p_cino); + check_string_option(&buf->b_p_cinsd); parse_cino(buf); #endif check_string_option(&buf->b_p_ft); diff --git a/src/structs.h b/src/structs.h index 5a76a599da..a1dbfbed28 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2881,6 +2881,7 @@ struct file_buffer int b_p_cin; // 'cindent' char_u *b_p_cino; // 'cinoptions' char_u *b_p_cink; // 'cinkeys' + char_u *b_p_cinsd; // 'cinscopedecls' #endif #if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT) char_u *b_p_cinw; // 'cinwords' diff --git a/src/testdir/test_cindent.vim b/src/testdir/test_cindent.vim index d8ea4e772e..dbd4aa006e 100644 --- a/src/testdir/test_cindent.vim +++ b/src/testdir/test_cindent.vim @@ -5319,6 +5319,49 @@ func Test_cindent_change_multline() close! endfunc +func Test_cindent_scopedecls() + new + setl cindent ts=4 sw=4 + setl cino=g0 + setl cinsd+=public\ slots,signals + + let code =<< trim [CODE] + class Foo + { + public: + virtual void foo() = 0; + public slots: + void onBar(); + signals: + void baz(); + private: + int x; + }; + [CODE] + + call append(0, code) + normal gg + normal ]]=][ + + let expected =<< trim [CODE] + class Foo + { + public: + virtual void foo() = 0; + public slots: + void onBar(); + signals: + void baz(); + private: + int x; + }; + + [CODE] + + call assert_equal(expected, getline(1, '$')) + enew! | close +endfunc + func Test_cindent_pragma() new setl cindent ts=4 sw=4 diff --git a/src/version.c b/src/version.c index f00fbcb27b..3cf9d188f0 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4702, /**/ 4701, /**/ From cb49a1d934d38cbc0d445af59b71ffe45cbcae75 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Apr 2022 13:08:00 +0100 Subject: [PATCH 04/11] patch 8.2.4703: memory leak in handling 'cinscopedecls' Problem: Memory leak in handling 'cinscopedecls'. Solution: Free the memory before returning. --- src/cindent.c | 35 +++++++++++++++++++---------------- src/version.c | 2 ++ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/cindent.c b/src/cindent.c index a22db9560e..268d274aec 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -425,32 +425,35 @@ cin_islabel_skip(char_u **s) static int cin_isscopedecl(char_u *p) { - size_t cinsd_len; - char_u *cinsd_buf; - char_u *cinsd; - size_t len; - char_u *skip; - char_u *s = cin_skipcomment(p); + size_t cinsd_len; + char_u *cinsd_buf; + char_u *cinsd; + size_t len; + char_u *skip; + char_u *s = cin_skipcomment(p); + int found = FALSE; cinsd_len = STRLEN(curbuf->b_p_cinsd) + 1; cinsd_buf = alloc(cinsd_len); - if (cinsd_buf != NULL) + if (cinsd_buf == NULL) + return FALSE; + + for (cinsd = curbuf->b_p_cinsd; *cinsd; ) { - for (cinsd = curbuf->b_p_cinsd; *cinsd; ) + len = copy_option_part(&cinsd, cinsd_buf, cinsd_len, ","); + if (STRNCMP(s, cinsd_buf, len) == 0) { - len = copy_option_part(&cinsd, cinsd_buf, cinsd_len, ","); - if (STRNCMP(s, cinsd_buf, len) == 0) + skip = cin_skipcomment(s + len); + if (*skip == ':' && skip[1] != ':') { - skip = cin_skipcomment(s + len); - if (*skip == ':' && skip[1] != ':') - return TRUE; + found = TRUE; + break; } } - - vim_free(cinsd_buf); } - return FALSE; + vim_free(cinsd_buf); + return found; } /* diff --git a/src/version.c b/src/version.c index 3cf9d188f0..bbbfeb713b 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4703, /**/ 4702, /**/ From f26c16144ddb27642c09f2cf5271afd163b36306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=3D=3FUTF-8=3Fq=3FDundar=3D20G=3DC3=3DB6c=3F=3D?= Date: Thu, 7 Apr 2022 13:26:34 +0100 Subject: [PATCH 05/11] patch 8.2.4704: using "else" after return or break increases indent Problem: Using "else" after return or break increases indent. Solution: Remove "else" and reduce indent. (Goc Dundar, closes #10099) --- src/fileio.c | 43 +++++++------- src/memline.c | 159 +++++++++++++++++++++++++------------------------- src/option.c | 48 ++++++++------- src/syntax.c | 86 +++++++++++++-------------- src/version.c | 2 + 5 files changed, 167 insertions(+), 171 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index af915c665f..439789e598 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1245,30 +1245,29 @@ retry: read_buf_col += n; break; } - else + + // Append whole line and new-line. Change NL + // to NUL to reverse the effect done below. + for (ni = 0; ni < n; ++ni) { - // Append whole line and new-line. Change NL - // to NUL to reverse the effect done below. - for (ni = 0; ni < n; ++ni) - { - if (p[ni] == NL) - ptr[tlen++] = NUL; - else - ptr[tlen++] = p[ni]; - } - ptr[tlen++] = NL; - read_buf_col = 0; - if (++read_buf_lnum > from) - { - // When the last line didn't have an - // end-of-line don't add it now either. - if (!curbuf->b_p_eol) - --tlen; - size = tlen; - eof = TRUE; - break; - } + if (p[ni] == NL) + ptr[tlen++] = NUL; + else + ptr[tlen++] = p[ni]; } + ptr[tlen++] = NL; + read_buf_col = 0; + if (++read_buf_lnum > from) + { + // When the last line didn't have an + // end-of-line don't add it now either. + if (!curbuf->b_p_eol) + --tlen; + size = tlen; + eof = TRUE; + break; + } + } } } diff --git a/src/memline.c b/src/memline.c index abd2360ae8..f38e029bd1 100644 --- a/src/memline.c +++ b/src/memline.c @@ -3165,94 +3165,93 @@ ml_append_int( */ break; } - else // pointer block full + // pointer block full + /* + * split the pointer block + * allocate a new pointer block + * move some of the pointer into the new block + * prepare for updating the parent block + */ + for (;;) // do this twice when splitting block 1 { - /* - * split the pointer block - * allocate a new pointer block - * move some of the pointer into the new block - * prepare for updating the parent block - */ - for (;;) // do this twice when splitting block 1 - { - hp_new = ml_new_ptr(mfp); - if (hp_new == NULL) // TODO: try to fix tree - goto theend; - pp_new = (PTR_BL *)(hp_new->bh_data); + hp_new = ml_new_ptr(mfp); + if (hp_new == NULL) // TODO: try to fix tree + goto theend; + pp_new = (PTR_BL *)(hp_new->bh_data); - if (hp->bh_bnum != 1) - break; + if (hp->bh_bnum != 1) + break; - /* - * if block 1 becomes full the tree is given an extra level - * The pointers from block 1 are moved into the new block. - * block 1 is updated to point to the new block - * then continue to split the new block - */ - mch_memmove(pp_new, pp, (size_t)page_size); - pp->pb_count = 1; - pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum; - pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count; - pp->pb_pointer[0].pe_old_lnum = 1; - pp->pb_pointer[0].pe_page_count = 1; - mf_put(mfp, hp, TRUE, FALSE); // release block 1 - hp = hp_new; // new block is to be split - pp = pp_new; - CHECK(stack_idx != 0, _("stack_idx should be 0")); - ip->ip_index = 0; - ++stack_idx; // do block 1 again later - } /* - * move the pointers after the current one to the new block - * If there are none, the new entry will be in the new block. + * if block 1 becomes full the tree is given an extra level + * The pointers from block 1 are moved into the new block. + * block 1 is updated to point to the new block + * then continue to split the new block */ - total_moved = pp->pb_count - pb_idx - 1; - if (total_moved) - { - mch_memmove(&pp_new->pb_pointer[0], + mch_memmove(pp_new, pp, (size_t)page_size); + pp->pb_count = 1; + pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum; + pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count; + pp->pb_pointer[0].pe_old_lnum = 1; + pp->pb_pointer[0].pe_page_count = 1; + mf_put(mfp, hp, TRUE, FALSE); // release block 1 + hp = hp_new; // new block is to be split + pp = pp_new; + CHECK(stack_idx != 0, _("stack_idx should be 0")); + ip->ip_index = 0; + ++stack_idx; // do block 1 again later + } + /* + * move the pointers after the current one to the new block + * If there are none, the new entry will be in the new block. + */ + total_moved = pp->pb_count - pb_idx - 1; + if (total_moved) + { + mch_memmove(&pp_new->pb_pointer[0], &pp->pb_pointer[pb_idx + 1], (size_t)(total_moved) * sizeof(PTR_EN)); - pp_new->pb_count = total_moved; - pp->pb_count -= total_moved - 1; - pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right; - pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right; - pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right; - if (lnum_right) - pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right; - } - else - { - pp_new->pb_count = 1; - pp_new->pb_pointer[0].pe_bnum = bnum_right; - pp_new->pb_pointer[0].pe_line_count = line_count_right; - pp_new->pb_pointer[0].pe_page_count = page_count_right; - pp_new->pb_pointer[0].pe_old_lnum = lnum_right; - } - pp->pb_pointer[pb_idx].pe_bnum = bnum_left; - pp->pb_pointer[pb_idx].pe_line_count = line_count_left; - pp->pb_pointer[pb_idx].pe_page_count = page_count_left; - if (lnum_left) - pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left; - lnum_left = 0; - lnum_right = 0; - - /* - * recompute line counts - */ - line_count_right = 0; - for (i = 0; i < (int)pp_new->pb_count; ++i) - line_count_right += pp_new->pb_pointer[i].pe_line_count; - line_count_left = 0; - for (i = 0; i < (int)pp->pb_count; ++i) - line_count_left += pp->pb_pointer[i].pe_line_count; - - bnum_left = hp->bh_bnum; - bnum_right = hp_new->bh_bnum; - page_count_left = 1; - page_count_right = 1; - mf_put(mfp, hp, TRUE, FALSE); - mf_put(mfp, hp_new, TRUE, FALSE); + pp_new->pb_count = total_moved; + pp->pb_count -= total_moved - 1; + pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right; + pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right; + pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right; + if (lnum_right) + pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right; } + else + { + pp_new->pb_count = 1; + pp_new->pb_pointer[0].pe_bnum = bnum_right; + pp_new->pb_pointer[0].pe_line_count = line_count_right; + pp_new->pb_pointer[0].pe_page_count = page_count_right; + pp_new->pb_pointer[0].pe_old_lnum = lnum_right; + } + pp->pb_pointer[pb_idx].pe_bnum = bnum_left; + pp->pb_pointer[pb_idx].pe_line_count = line_count_left; + pp->pb_pointer[pb_idx].pe_page_count = page_count_left; + if (lnum_left) + pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left; + lnum_left = 0; + lnum_right = 0; + + /* + * recompute line counts + */ + line_count_right = 0; + for (i = 0; i < (int)pp_new->pb_count; ++i) + line_count_right += pp_new->pb_pointer[i].pe_line_count; + line_count_left = 0; + for (i = 0; i < (int)pp->pb_count; ++i) + line_count_left += pp->pb_pointer[i].pe_line_count; + + bnum_left = hp->bh_bnum; + bnum_right = hp_new->bh_bnum; + page_count_left = 1; + page_count_right = 1; + mf_put(mfp, hp, TRUE, FALSE); + mf_put(mfp, hp_new, TRUE, FALSE); + } /* diff --git a/src/option.c b/src/option.c index 49123aa36b..f636985546 100644 --- a/src/option.c +++ b/src/option.c @@ -4384,38 +4384,36 @@ set_option_value( #endif if (flags & P_STRING) return set_string_option(opt_idx, string, opt_flags); - else + + varp = get_varp_scope(&(options[opt_idx]), opt_flags); + if (varp != NULL) // hidden option is not changed { - varp = get_varp_scope(&(options[opt_idx]), opt_flags); - if (varp != NULL) // hidden option is not changed + if (number == 0 && string != NULL) { - if (number == 0 && string != NULL) + int idx; + + // Either we are given a string or we are setting option + // to zero. + for (idx = 0; string[idx] == '0'; ++idx) + ; + if (string[idx] != NUL || idx == 0) { - int idx; + // There's another character after zeros or the string + // is empty. In both cases, we are trying to set a + // num option using a string. + semsg(_(e_number_required_after_str_equal_str), + name, string); + return NULL; // do nothing as we hit an error - // Either we are given a string or we are setting option - // to zero. - for (idx = 0; string[idx] == '0'; ++idx) - ; - if (string[idx] != NUL || idx == 0) - { - // There's another character after zeros or the string - // is empty. In both cases, we are trying to set a - // num option using a string. - semsg(_(e_number_required_after_str_equal_str), - name, string); - return NULL; // do nothing as we hit an error - - } } - if (flags & P_NUM) - return set_num_option(opt_idx, varp, number, - NULL, 0, opt_flags); - else - return set_bool_option(opt_idx, varp, (int)number, - opt_flags); } + if (flags & P_NUM) + return set_num_option(opt_idx, varp, number, + NULL, 0, opt_flags); + else + return set_bool_option(opt_idx, varp, (int)number, opt_flags); } + } return NULL; } diff --git a/src/syntax.c b/src/syntax.c index 74687cb4d9..086d9d755e 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -2504,55 +2504,53 @@ check_state_ends(void) next_match_col = MAXCOL; break; } - else + + // handle next_list, unless at end of line and no "skipnl" or + // "skipempty" + current_next_list = cur_si->si_next_list; + current_next_flags = cur_si->si_flags; + if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)) + && syn_getcurline()[current_col] == NUL) + current_next_list = NULL; + + // When the ended item has "extend", another item with + // "keepend" now needs to check for its end. + had_extend = (cur_si->si_flags & HL_EXTEND); + + pop_current_state(); + + if (current_state.ga_len == 0) + break; + + if (had_extend && keepend_level >= 0) { - // handle next_list, unless at end of line and no "skipnl" or - // "skipempty" - current_next_list = cur_si->si_next_list; - current_next_flags = cur_si->si_flags; - if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)) - && syn_getcurline()[current_col] == NUL) - current_next_list = NULL; - - // When the ended item has "extend", another item with - // "keepend" now needs to check for its end. - had_extend = (cur_si->si_flags & HL_EXTEND); - - pop_current_state(); - + syn_update_ends(FALSE); if (current_state.ga_len == 0) break; + } - if (had_extend && keepend_level >= 0) - { - syn_update_ends(FALSE); - if (current_state.ga_len == 0) - break; - } + cur_si = &CUR_STATE(current_state.ga_len - 1); - cur_si = &CUR_STATE(current_state.ga_len - 1); - - /* - * Only for a region the search for the end continues after - * the end of the contained item. If the contained match - * included the end-of-line, break here, the region continues. - * Don't do this when: - * - "keepend" is used for the contained item - * - not at the end of the line (could be end="x$"me=e-1). - * - "excludenl" is used (HL_HAS_EOL won't be set) - */ - if (cur_si->si_idx >= 0 - && SYN_ITEMS(syn_block)[cur_si->si_idx].sp_type - == SPTYPE_START - && !(cur_si->si_flags & (HL_MATCH | HL_KEEPEND))) - { - update_si_end(cur_si, (int)current_col, TRUE); - check_keepend(); - if ((current_next_flags & HL_HAS_EOL) - && keepend_level < 0 - && syn_getcurline()[current_col] == NUL) - break; - } + /* + * Only for a region the search for the end continues after + * the end of the contained item. If the contained match + * included the end-of-line, break here, the region continues. + * Don't do this when: + * - "keepend" is used for the contained item + * - not at the end of the line (could be end="x$"me=e-1). + * - "excludenl" is used (HL_HAS_EOL won't be set) + */ + if (cur_si->si_idx >= 0 + && SYN_ITEMS(syn_block)[cur_si->si_idx].sp_type + == SPTYPE_START + && !(cur_si->si_flags & (HL_MATCH | HL_KEEPEND))) + { + update_si_end(cur_si, (int)current_col, TRUE); + check_keepend(); + if ((current_next_flags & HL_HAS_EOL) + && keepend_level < 0 + && syn_getcurline()[current_col] == NUL) + break; } } else diff --git a/src/version.c b/src/version.c index bbbfeb713b..1bc106337c 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4704, /**/ 4703, /**/ From 6d4e725a3447af6f69305fdc9f1e1ff8d82e3863 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Apr 2022 13:58:04 +0100 Subject: [PATCH 06/11] patch 8.2.4705: jump list marker disappears Problem: Jump list marker disappears. Solution: Reset reg_executing later. (closes #10111, closes #10100) --- src/ex_docmd.c | 4 ++++ src/getchar.c | 29 +++++++++++++++++++++++++---- src/globals.h | 2 ++ src/structs.h | 1 + src/testdir/test_registers.vim | 18 ++++++++++++++++++ src/version.c | 2 ++ 6 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 2d5752445b..90ca7ade2b 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1733,6 +1733,7 @@ do_one_cmd( exarg_T ea; // Ex command arguments cmdmod_T save_cmdmod; int save_reg_executing = reg_executing; + int save_pending_end_reg_executing = pending_end_reg_executing; int ni; // set when Not Implemented char_u *cmd; int starts_with_colon = FALSE; @@ -2630,6 +2631,7 @@ doend: undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; reg_executing = save_reg_executing; + pending_end_reg_executing = save_pending_end_reg_executing; if (ea.nextcmd && *ea.nextcmd == NUL) // not really a next command ea.nextcmd = NULL; @@ -8456,6 +8458,7 @@ save_current_state(save_state_T *sst) sst->save_finish_op = finish_op; sst->save_opcount = opcount; sst->save_reg_executing = reg_executing; + sst->save_pending_end_reg_executing = pending_end_reg_executing; msg_scroll = FALSE; // no msg scrolling in Normal mode restart_edit = 0; // don't go to Insert mode @@ -8485,6 +8488,7 @@ restore_current_state(save_state_T *sst) finish_op = sst->save_finish_op; opcount = sst->save_opcount; reg_executing = sst->save_reg_executing; + pending_end_reg_executing = sst->save_pending_end_reg_executing; msg_didout |= sst->save_msg_didout; // don't reset msg_didout now current_sctx.sc_version = sst->save_script_version; diff --git a/src/getchar.c b/src/getchar.c index b81f64a65c..29ad56e6a1 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -1421,7 +1421,7 @@ static int old_mouse_row; // mouse_row related to old_char static int old_mouse_col; // mouse_col related to old_char static int old_KeyStuffed; // whether old_char was stuffed -static int can_get_old_char() +static int can_get_old_char(void) { // If the old character was not stuffed and characters have been added to // the stuff buffer, need to first get the stuffed characters instead. @@ -2950,7 +2950,7 @@ handle_mapping( /* * unget one character (can only be done once!) - * If the character was stuffed, vgetc() will get it next time it was called. + * If the character was stuffed, vgetc() will get it next time it is called. * Otherwise vgetc() will only get it when the stuff buffer is empty. */ void @@ -2963,6 +2963,27 @@ vungetc(int c) old_KeyStuffed = KeyStuffed; } +/* + * When peeking and not getting a character, reg_executing cannot be cleared + * yet, so set a flag to clear it later. + */ + static void +check_end_reg_executing(int advance) +{ + if (reg_executing != 0 && (typebuf.tb_maplen == 0 + || pending_end_reg_executing)) + { + if (advance) + { + reg_executing = 0; + pending_end_reg_executing = FALSE; + } + else + pending_end_reg_executing = TRUE; + } + +} + /* * Get a byte: * 1. from the stuffbuffer @@ -3026,8 +3047,7 @@ vgetorpeek(int advance) init_typebuf(); start_stuff(); - if (advance && typebuf.tb_maplen == 0) - reg_executing = 0; + check_end_reg_executing(advance); do { /* @@ -3068,6 +3088,7 @@ vgetorpeek(int advance) #ifdef FEAT_CMDL_INFO int showcmd_idx; #endif + check_end_reg_executing(advance); /* * ui_breakcheck() is slow, don't use it too often when * inside a mapping. But call it each time for typed diff --git a/src/globals.h b/src/globals.h index f690efffc4..da1ff76391 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1123,6 +1123,8 @@ EXTERN int ex_no_reprint INIT(= FALSE); // no need to print after z or p EXTERN int reg_recording INIT(= 0); // register for recording or zero EXTERN int reg_executing INIT(= 0); // register being executed or zero +// Flag set when peeking a character and found the end of executed register +EXTERN int pending_end_reg_executing INIT(= 0); // Set when a modifyOtherKeys sequence was seen, then simplified mappings will // no longer be used. diff --git a/src/structs.h b/src/structs.h index a1dbfbed28..b8648a5455 100644 --- a/src/structs.h +++ b/src/structs.h @@ -4302,6 +4302,7 @@ typedef struct { int save_finish_op; int save_opcount; int save_reg_executing; + int save_pending_end_reg_executing; int save_script_version; tasave_T tabuf; } save_state_T; diff --git a/src/testdir/test_registers.vim b/src/testdir/test_registers.vim index 078b78dfdf..51543c00c1 100644 --- a/src/testdir/test_registers.vim +++ b/src/testdir/test_registers.vim @@ -759,6 +759,24 @@ func Test_record_in_select_mode() bwipe! endfunc +func Test_end_reg_executing() + nnoremap s + let @a = 's' + call feedkeys("@aqaq\", 'tx') + call assert_equal('', @a) + call assert_equal('', getline(1)) + + call setline(1, 'aaa') + nnoremap s qa + let @a = 'fa' + call feedkeys("@asq\", 'tx') + call assert_equal('', @a) + call assert_equal('aaa', getline(1)) + + nunmap s + bwipe! +endfunc + " Make sure that y_append is correctly reset " and the previous register is working as expected func Test_register_y_append_reset() diff --git a/src/version.c b/src/version.c index 1bc106337c..62623614a2 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4705, /**/ 4704, /**/ From 6a06940f8ae7283999c83ccdf268540220573105 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Apr 2022 14:08:29 +0100 Subject: [PATCH 07/11] patch 8.2.4706: buffer remains active with WinClosed and tabpages Problem: Buffer remains active if a WinClosed event throws an exception when there are multiple tabpages. Solution: Ignore aborting() when closing the buffer. (closes #10101) --- src/testdir/test_autocmd.vim | 17 +++++++++++++++++ src/version.c | 2 ++ src/window.c | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 89023a1fb7..eb1fa046c5 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -365,6 +365,23 @@ func Test_WinClosed_throws() augroup! test-WinClosed endfunc +func Test_WinClosed_throws_with_tabs() + tabnew + let bnr = bufnr() + call assert_equal(1, bufloaded(bnr)) + augroup test-WinClosed + autocmd WinClosed * throw 'foo' + augroup END + try + close + catch /.*/ + endtry + call assert_equal(0, bufloaded(bnr)) + + autocmd! test-WinClosed + augroup! test-WinClosed +endfunc + func s:AddAnAutocmd() augroup vimBarTest au BufReadCmd * echo 'hello' diff --git a/src/version.c b/src/version.c index 62623614a2..d0205d7e33 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4706, /**/ 4705, /**/ diff --git a/src/window.c b/src/window.c index 8ec4823a98..f763475892 100644 --- a/src/window.c +++ b/src/window.c @@ -2814,7 +2814,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) if (win->w_buffer != NULL) // Close the link to the buffer. close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, - FALSE, FALSE); + FALSE, TRUE); // Careful: Autocommands may have closed the tab page or made it the // current tab page. From 8c9796085071950f9a03ca0fe116608e4f86aac2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Apr 2022 15:08:01 +0100 Subject: [PATCH 08/11] patch 8.2.4707: redrawing could be a bit more efficient Problem: Redrawing could be a bit more efficient. Solution: Optimize redrawing. (closes #10105) --- src/change.c | 8 +++- src/edit.c | 39 ++++++++----------- .../Test_cursorcolumn_insert_on_tab_3.dump | 8 ++++ src/testdir/test_highlight.vim | 8 ++++ src/version.c | 2 + 5 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 src/testdir/dumps/Test_cursorcolumn_insert_on_tab_3.dump diff --git a/src/change.c b/src/change.c index afc32b7241..bc9195be44 100644 --- a/src/change.c +++ b/src/change.c @@ -640,9 +640,13 @@ changed_common( if (hasAnyFolding(wp)) set_topline(wp, wp->w_topline); #endif - // Relative numbering may require updating more. + // If lines have been added or removed, relative numbering always + // requires a redraw. if (wp->w_p_rnu && xtra != 0) - redraw_win_later(wp, SOME_VALID); + { + wp->w_last_cursor_lnum_rnu = 0; + redraw_win_later(wp, VALID); + } #ifdef FEAT_SYN_HL // Cursor line highlighting probably need to be updated with // "VALID" if it's below the change. diff --git a/src/edit.c b/src/edit.c index c52583a8b6..53e86ff18f 100644 --- a/src/edit.c +++ b/src/edit.c @@ -293,14 +293,9 @@ edit( conceal_check_cursor_line(cursor_line_was_concealed); #endif - // Need to recompute the cursor position, it might move when the cursor - // is on a TAB or special character. - // ptr2cells() treats a TAB character as double-width. - if (ptr2cells(ml_get_cursor()) > 1) - { - curwin->w_valid &= ~VALID_VIRTCOL; - curs_columns(TRUE); - } + // need to position cursor again when on a TAB + if (gchar_cursor() == TAB) + curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); /* * Enable langmap or IME, indicated by 'iminsert'. @@ -3149,21 +3144,20 @@ mb_replace_pop_ins(int cc) replace_push(c); break; } + + buf[0] = c; + for (i = 1; i < n; ++i) + buf[i] = replace_pop(); + if (utf_iscomposing(utf_ptr2char(buf))) + ins_bytes_len(buf, n); else { - buf[0] = c; - for (i = 1; i < n; ++i) - buf[i] = replace_pop(); - if (utf_iscomposing(utf_ptr2char(buf))) - ins_bytes_len(buf, n); - else - { - // Not a composing char, put it back. - for (i = n - 1; i >= 0; --i) - replace_push(buf[i]); - break; - } + // Not a composing char, put it back. + for (i = n - 1; i >= 0; --i) + replace_push(buf[i]); + break; } + } } @@ -3702,8 +3696,9 @@ ins_esc( State = NORMAL; trigger_modechanged(); - // need to position cursor again (e.g. when on a TAB ) - changed_cline_bef_curs(); + // need to position cursor again when on a TAB + if (gchar_cursor() == TAB) + curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); setmouse(); #ifdef CURSOR_SHAPE diff --git a/src/testdir/dumps/Test_cursorcolumn_insert_on_tab_3.dump b/src/testdir/dumps/Test_cursorcolumn_insert_on_tab_3.dump new file mode 100644 index 0000000000..9d0cbed968 --- /dev/null +++ b/src/testdir/dumps/Test_cursorcolumn_insert_on_tab_3.dump @@ -0,0 +1,8 @@ +|1+0&#ffffff0|2|3|4|5|6|7|8+0&#e0e0e08|9+0&#ffffff0| @65 +|a| @5> |b| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |(|i|n|s|e|r|t|)| |-@1| +0&&@42|2|,|2|-|8| @8|A|l@1| diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim index 51a25242fe..3400052a7c 100644 --- a/src/testdir/test_highlight.vim +++ b/src/testdir/test_highlight.vim @@ -610,6 +610,14 @@ func Test_cursorcolumn_insert_on_tab() call TermWait(buf) call VerifyScreenDump(buf, 'Test_cursorcolumn_insert_on_tab_2', {}) + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_cursorcolumn_insert_on_tab_3', {}) + + call term_sendkeys(buf, 'i') + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_cursorcolumn_insert_on_tab_2', {}) + call StopVimInTerminal(buf) call delete('Xcuc_insert_on_tab') endfunc diff --git a/src/version.c b/src/version.c index d0205d7e33..bd63e9317d 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4707, /**/ 4706, /**/ From 177847e67a495f80a15b6dfd0a3fcd151b44249e Mon Sep 17 00:00:00 2001 From: Julien Voisin Date: Thu, 7 Apr 2022 16:01:13 +0100 Subject: [PATCH 09/11] patch 8.2.4708: PHP test files are not recognized Problem: PHP test files are not recognized. Solution: Add the *.phpt pattern. (Julien Voisin, closes #10112) --- runtime/filetype.vim | 7 ++++--- src/testdir/test_filetype.vim | 2 +- src/version.c | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 9d63a7fe89..4aa5743dae 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1352,9 +1352,10 @@ au BufNewFile,BufRead *.pm au BufNewFile,BufRead *.pod setf pod " Php, php3, php4, etc. -" Also Phtml (was used for PHP 2 in the past) -" Also .ctp for Cake template file -au BufNewFile,BufRead *.php,*.php\d,*.phtml,*.ctp setf php +" Also Phtml (was used for PHP 2 in the past). +" Also .ctp for Cake template file. +" Also .phpt for php tests. +au BufNewFile,BufRead *.php,*.php\d,*.phtml,*.ctp,*.phpt setf php " PHP config au BufNewFile,BufRead php.ini-* setf dosini diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index dc2dc5ae4e..c8c159c44e 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -396,7 +396,7 @@ let s:filename_checks = { \ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'], \ 'pf': ['pf.conf'], \ 'pfmain': ['main.cf'], - \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp'], + \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp', 'file.phpt'], \ 'lpc': ['file.lpc', 'file.ulpc'], \ 'pike': ['file.pike', 'file.pmod'], \ 'cmod': ['file.cmod'], diff --git a/src/version.c b/src/version.c index bd63e9317d..a7bfeceaca 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4708, /**/ 4707, /**/ From 5017c66bd461eab46094e076ad1aa818e246ce9d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Apr 2022 18:06:08 +0100 Subject: [PATCH 10/11] patch 8.2.4709: after :redraw the statusline highlight might be used Problem: After :redraw the statusline highlight might be used. Solution: Clear the screen attribute after redrawing the screen. (closes #10108) --- src/ex_docmd.c | 3 +++ src/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 90ca7ade2b..0b8825959e 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -8290,6 +8290,9 @@ ex_redraw(exarg_T *eap) RedrawingDisabled = r; p_lz = p; + // After drawing the statusline screen_attr may still be set. + screen_stop_highlight(); + // Reset msg_didout, so that a message that's there is overwritten. msg_didout = FALSE; msg_col = 0; diff --git a/src/version.c b/src/version.c index a7bfeceaca..7eec582d98 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4709, /**/ 4708, /**/ From ac72c21da696cf6c31630a9e5ff4c0d3e2049c11 Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Thu, 7 Apr 2022 21:00:53 +0100 Subject: [PATCH 11/11] patch 8.2.4710: smart indenting does not work after completion Problem: Smart indenting does not work after completion. Solution: Set "can_si". (Christian Brabandt, closes #10113, closes #558) --- src/edit.c | 3 +++ src/testdir/test_ins_complete.vim | 19 +++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 24 insertions(+) diff --git a/src/edit.c b/src/edit.c index 53e86ff18f..f30edd5c79 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1293,6 +1293,9 @@ docomplete: disable_fold_update--; #endif compl_busy = FALSE; +#ifdef FEAT_SMARTINDENT + can_si = TRUE; // allow smartindenting +#endif break; case Ctrl_Y: // copy from previous line or scroll down diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index 3712abe690..75ec03cb37 100644 --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -2132,4 +2132,23 @@ func Test_thesaurusfunc_callback() %bw! endfunc +func FooBarComplete(findstart, base) + if a:findstart + return col('.') - 1 + else + return ["Foo", "Bar", "}"] + endif +endfunc + +func Test_complete_smartindent() + new + setlocal smartindent completefunc=FooBarComplete + + exe "norm! o{\\\\}\\" + let result = getline(1,'$') + call assert_equal(['', '{','}',''], result) + bw! + delfunction! FooBarComplete +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 7eec582d98..956100304b 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4710, /**/ 4709, /**/