aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/labeler.yml6
-rw-r--r--.github/workflows/reviews.yml4
-rw-r--r--runtime/autoload/freebasic.vim3
-rw-r--r--runtime/doc/builtin.txt21
-rw-r--r--src/nvim/api/keysets.lua4
-rw-r--r--src/nvim/buffer.c49
-rw-r--r--src/nvim/eval.c9
-rw-r--r--src/nvim/eval.lua4
-rw-r--r--src/nvim/eval/funcs.c56
-rw-r--r--src/nvim/highlight.c4
-rw-r--r--src/nvim/option.c7
-rw-r--r--src/nvim/screen.c2
-rw-r--r--src/nvim/testdir/test_search.vim2
-rw-r--r--src/nvim/testdir/test_syntax.vim50
-rw-r--r--src/nvim/testdir/test_winbuf_close.vim19
-rw-r--r--src/nvim/window.c14
-rw-r--r--test/functional/api/highlight_spec.lua6
17 files changed, 206 insertions, 54 deletions
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 0e20e96cb6..08f0ce1763 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -27,11 +27,9 @@ jobs:
PR_TITLE: ${{ github.event.pull_request.title }}
steps:
- name: "Extract commit type and add as label"
- continue-on-error: true
- run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|([[:alpha:]]+)(\(.*\))?!?:.*|\1|')"
+ run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|([[:alpha:]]+)(\(.*\))?!?:.*|\1|')" || true
- name: "Extract commit scope and add as label"
- continue-on-error: true
- run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|[[:alpha:]]+\((.+)\)!?:.*|\1|')"
+ run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|[[:alpha:]]+\((.+)\)!?:.*|\1|')" || true
upload-pr-number:
runs-on: ubuntu-latest
diff --git a/.github/workflows/reviews.yml b/.github/workflows/reviews.yml
index 965adc2ab0..e2253988ba 100644
--- a/.github/workflows/reviews.yml
+++ b/.github/workflows/reviews.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- if: github.event_name == 'workflow_run'
name: 'Download artifact with PR number'
- uses: actions/github-script@v5
+ uses: actions/github-script@v6
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
@@ -38,7 +38,7 @@ jobs:
run: unzip pr_number.zip
- name: 'Request reviewers'
- uses: actions/github-script@v5
+ uses: actions/github-script@v6
with:
script: |
// The number of the pull request that triggered this run. If label
diff --git a/runtime/autoload/freebasic.vim b/runtime/autoload/freebasic.vim
index fe6d2745be..428cf1382b 100644
--- a/runtime/autoload/freebasic.vim
+++ b/runtime/autoload/freebasic.vim
@@ -23,8 +23,7 @@ function! freebasic#GetDialect() abort
let save_cursor = getcurpos()
call cursor(1, 1)
- " let lnum = search(pat, 'n', '', '', skip) " 'skip' needs 8.2.0915
- let lnum = search(pat, 'n', '', '')
+ let lnum = search(pat, 'n', '', '', skip)
call setpos('.', save_cursor)
if lnum
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index f371ad92cc..35a232c0c2 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -380,7 +380,7 @@ screencol() Number current cursor column
screenpos({winid}, {lnum}, {col}) Dict screen row and col of a text character
screenrow() Number current cursor row
screenstring({row}, {col}) String characters at screen position
-search({pattern} [, {flags} [, {stopline} [, {timeout}]]])
+search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Number search for {pattern}
searchcount([{options}]) Dict Get or update the last search count
searchdecl({name} [, {global} [, {thisblock}]])
@@ -389,7 +389,7 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip} [...]]])
Number search for other end of start/end pair
searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [...]]])
List search for other end of start/end pair
-searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]])
+searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
List search for {pattern}
server2client({clientid}, {string})
Number send reply string
@@ -6169,8 +6169,9 @@ screenstring({row}, {col}) *screenstring()*
Can also be used as a |method|: >
GetRow()->screenstring(col)
-
-search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
+<
+ *search()*
+search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Search for regexp pattern {pattern}. The search starts at the
cursor position (you can use |cursor()| to set it).
@@ -6222,6 +6223,15 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
The value must not be negative. A zero value is like not
giving the argument.
+ If the {skip} expression is given it is evaluated with the
+ cursor positioned on the start of a match. If it evaluates to
+ non-zero this match is skipped. This can be used, for
+ example, to skip a match in a comment or a string.
+ {skip} can be a string, which is evaluated as an expression, a
+ function reference or a lambda.
+ When {skip} is omitted or empty, every match is accepted.
+ When evaluating {skip} causes an error the search is aborted
+ and -1 returned.
*search()-sub-match*
With the 'p' flag the returned value is one more than the
first sub-match in \(\). One if none of them matched but the
@@ -6505,7 +6515,8 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip}
<
See |match-parens| for a bigger and more useful example.
-searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *searchpos()*
+ *searchpos()*
+searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Same as |search()|, but returns a |List| with the line and
column position of the match. The first element of the |List|
is the line number and the second element is the byte index of
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index 075e2c48d2..f6dce1905e 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -81,10 +81,12 @@ return {
highlight = {
"bold";
"standout";
+ "strikethrough";
"underline";
"undercurl";
"italic";
"reverse";
+ "nocombine";
"default";
"global";
"cterm";
@@ -100,10 +102,12 @@ return {
highlight_cterm = {
"bold";
"standout";
+ "strikethrough";
"underline";
"undercurl";
"italic";
"reverse";
+ "nocombine";
};
}
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index ee704bd1bd..38b045b31c 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -5455,30 +5455,43 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
return false;
}
-int buf_signcols(buf_T *buf)
+static int buf_signcols_inner(buf_T *buf, int maximum)
{
- if (!buf->b_signcols_valid) {
- sign_entry_T *sign; // a sign in the sign list
- int signcols = 0;
- int linesum = 0;
- linenr_T curline = 0;
-
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_lnum > curline) {
- if (linesum > signcols) {
- signcols = linesum;
+ sign_entry_T *sign; // a sign in the sign list
+ int signcols = 0;
+ int linesum = 0;
+ linenr_T curline = 0;
+
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_lnum > curline) {
+ if (linesum > signcols) {
+ signcols = linesum;
+ if (signcols >= maximum) {
+ return maximum;
}
- curline = sign->se_lnum;
- linesum = 0;
- }
- if (sign->se_has_text_or_icon) {
- linesum++;
}
+ curline = sign->se_lnum;
+ linesum = 0;
+ }
+ if (sign->se_has_text_or_icon) {
+ linesum++;
}
- if (linesum > signcols) {
- signcols = linesum;
+ }
+
+ if (linesum > signcols) {
+ signcols = linesum;
+ if (signcols >= maximum) {
+ return maximum;
}
+ }
+
+ return signcols;
+}
+int buf_signcols(buf_T *buf, int maximum)
+{
+ if (!buf->b_signcols_valid) {
+ int signcols = buf_signcols_inner(buf, maximum);
// Check if we need to redraw
if (signcols != buf->b_signcols) {
buf->b_signcols = signcols;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index c197754685..4b83bda804 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -766,6 +766,15 @@ static int eval1_emsg(char_u **arg, typval_T *rettv, bool evaluate)
return ret;
}
+/// @return whether a typval is a valid expression to pass to eval_expr_typval()
+/// or eval_expr_to_bool(). An empty string returns false;
+bool eval_expr_valid_arg(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_CONST
+{
+ return tv->v_type != VAR_UNKNOWN
+ && (tv->v_type != VAR_STRING || (tv->vval.v_string != NULL && *tv->vval.v_string != NUL));
+}
+
int eval_expr_typval(const typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 1e39854c86..05e91a658f 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -307,12 +307,12 @@ return {
screenpos={args=3, base=1},
screenrow={},
screenstring={args=2, base=1},
- search={args={1, 4}, base=1},
+ search={args={1, 5}, base=1},
searchcount={args={0, 1}, base=1},
searchdecl={args={1, 3}, base=1},
searchpair={args={3, 7}},
searchpairpos={args={3, 7}},
- searchpos={args={1, 4}, base=1},
+ searchpos={args={1, 5}, base=1},
serverlist={},
serverstart={args={0, 1}},
serverstop={args=1},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index db4fb06a73..8beacc9988 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -8237,6 +8237,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
int options = SEARCH_KEEP;
int subpatnum;
searchit_arg_T sia;
+ bool use_skip = false;
const char *const pat = tv_get_string(&argvars[0]);
dir = get_search_arg(&argvars[1], flagsp); // May set p_ws.
@@ -8254,7 +8255,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
options |= SEARCH_COL;
}
- // Optional arguments: line number to stop searching and timeout.
+ // Optional arguments: line number to stop searching, timeout and skip.
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[2], NULL);
if (lnum_stop < 0) {
@@ -8265,6 +8266,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
if (time_limit < 0) {
goto theend;
}
+ use_skip = eval_expr_valid_arg(&argvars[4]);
}
}
@@ -8284,11 +8286,46 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
pos = save_cursor = curwin->w_cursor;
+ pos_T firstpos = { 0 };
memset(&sia, 0, sizeof(sia));
sia.sa_stop_lnum = (linenr_T)lnum_stop;
sia.sa_tm = &tm;
- subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,
- options, RE_SEARCH, &sia);
+
+ // Repeat until {skip} returns false.
+ for (;;) {
+ subpatnum
+ = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1, options, RE_SEARCH, &sia);
+ // finding the first match again means there is no match where {skip}
+ // evaluates to zero.
+ if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
+ subpatnum = FAIL;
+ }
+
+ if (subpatnum == FAIL || !use_skip) {
+ // didn't find it or no skip argument
+ break;
+ }
+ firstpos = pos;
+
+ // If the skip expression matches, ignore this match.
+ {
+ const pos_T save_pos = curwin->w_cursor;
+
+ curwin->w_cursor = pos;
+ bool err = false;
+ const bool do_skip = eval_expr_to_bool(&argvars[4], &err);
+ curwin->w_cursor = save_pos;
+ if (err) {
+ // Evaluating {skip} caused an error, break here.
+ subpatnum = FAIL;
+ break;
+ }
+ if (!do_skip) {
+ break;
+ }
+ }
+ }
+
if (subpatnum != FAIL) {
if (flags & SP_SUBPAT) {
retval = subpatnum;
@@ -8748,13 +8785,9 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
|| argvars[4].v_type == VAR_UNKNOWN) {
skip = NULL;
} else {
+ // Type is checked later.
skip = &argvars[4];
- if (skip->v_type != VAR_FUNC
- && skip->v_type != VAR_PARTIAL
- && skip->v_type != VAR_STRING) {
- semsg(_(e_invarg2), tv_get_string(&argvars[4]));
- goto theend; // Type error.
- }
+
if (argvars[5].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[5], NULL);
if (lnum_stop < 0) {
@@ -8865,10 +8898,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
}
if (skip != NULL) {
- // Empty string means to not use the skip expression.
- if (skip->v_type == VAR_STRING || skip->v_type == VAR_FUNC) {
- use_skip = skip->vval.v_string != NULL && *skip->vval.v_string != NUL;
- }
+ use_skip = eval_expr_valid_arg(skip);
}
save_cursor = curwin->w_cursor;
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 87c090e594..fcd91cdf16 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -815,6 +815,8 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
CHECK_FLAG(dict, mask, undercurl, , HL_UNDERCURL);
CHECK_FLAG(dict, mask, italic, , HL_ITALIC);
CHECK_FLAG(dict, mask, reverse, , HL_INVERSE);
+ CHECK_FLAG(dict, mask, strikethrough, , HL_STRIKETHROUGH);
+ CHECK_FLAG(dict, mask, nocombine, , HL_NOCOMBINE);
CHECK_FLAG(dict, mask, default, _, HL_DEFAULT);
CHECK_FLAG(dict, mask, global, , HL_GLOBAL);
@@ -871,6 +873,8 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
CHECK_FLAG(cterm, cterm_mask, undercurl, , HL_UNDERCURL);
CHECK_FLAG(cterm, cterm_mask, italic, , HL_ITALIC);
CHECK_FLAG(cterm, cterm_mask, reverse, , HL_INVERSE);
+ CHECK_FLAG(cterm, cterm_mask, strikethrough, , HL_STRIKETHROUGH);
+ CHECK_FLAG(cterm, cterm_mask, nocombine, , HL_NOCOMBINE);
} else if (HAS_KEY(dict->cterm)) {
api_set_error(err, kErrorTypeValidation, "'cterm' must be a Dictionary.");
diff --git a/src/nvim/option.c b/src/nvim/option.c
index dddf926b9a..df5f352258 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -8046,7 +8046,6 @@ int win_signcol_count(win_T *wp)
/// Return the number of requested sign columns, based on user / configuration.
int win_signcol_configured(win_T *wp, int *is_fixed)
{
- int minimum = 0, maximum = 1, needed_signcols;
const char *scl = (const char *)wp->w_p_scl;
if (is_fixed) {
@@ -8059,7 +8058,6 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
&& (wp->w_p_nu || wp->w_p_rnu)))) {
return 0;
}
- needed_signcols = buf_signcols(wp->w_buffer);
// yes or yes
if (!strncmp(scl, "yes:", 4)) {
@@ -8075,6 +8073,8 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
*is_fixed = 0;
}
+ int minimum = 0, maximum = 1;
+
if (!strncmp(scl, "auto:", 5)) {
// Variable depending on a configuration
maximum = scl[5] - '0';
@@ -8085,7 +8085,8 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
}
}
- int ret = MAX(minimum, MIN(maximum, needed_signcols));
+ int needed_signcols = buf_signcols(wp->w_buffer, maximum);
+ int ret = MAX(minimum, needed_signcols);
assert(ret <= SIGN_SHOW_MAX);
return ret;
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 0644a08210..6dcabffb7d 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -794,7 +794,7 @@ static void win_update(win_T *wp, Providers *providers)
// If we can compute a change in the automatic sizing of the sign column
// under 'signcolumn=auto:X' and signs currently placed in the buffer, better
// figuring it out here so we can redraw the entire screen for it.
- buf_signcols(buf);
+ win_signcol_count(wp);
type = wp->w_redr_type;
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
index 2a1a93b5e3..a3d5ca96a1 100644
--- a/src/nvim/testdir/test_search.vim
+++ b/src/nvim/testdir/test_search.vim
@@ -378,7 +378,6 @@ func Test_searchpair_errors()
call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
- call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
@@ -390,7 +389,6 @@ func Test_searchpairpos_errors()
call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
- call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim
index 757866f5dc..b047b53b6f 100644
--- a/src/nvim/testdir/test_syntax.vim
+++ b/src/nvim/testdir/test_syntax.vim
@@ -728,6 +728,56 @@ func Test_syntax_foldlevel()
quit!
endfunc
+func Test_search_syntax_skip()
+ new
+ let lines =<< trim END
+
+ /* This is VIM */
+ Another Text for VIM
+ let a = "VIM"
+ END
+ call setline(1, lines)
+ syntax on
+ syntax match Comment "^/\*.*\*/"
+ syntax match String '".*"'
+
+ " Skip argument using string evaluation.
+ 1
+ call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"')
+ call assert_equal('Another Text for VIM', getline('.'))
+ 1
+ call search('VIM', 'w', '', 0, 'synIDattr(synID(line("."), col("."), 1), "name") !~? "string"')
+ call assert_equal(' let a = "VIM"', getline('.'))
+
+ " Skip argument using Lambda.
+ 1
+ call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"})
+ call assert_equal('Another Text for VIM', getline('.'))
+
+ 1
+ call search('VIM', 'w', '', 0, { -> synIDattr(synID(line("."), col("."), 1), "name") !~? "string"})
+ call assert_equal(' let a = "VIM"', getline('.'))
+
+ " Skip argument using funcref.
+ func InComment()
+ return synIDattr(synID(line("."), col("."), 1), "name") =~? "comment"
+ endfunc
+ func InString()
+ return synIDattr(synID(line("."), col("."), 1), "name") !~? "string"
+ endfunc
+ 1
+ call search('VIM', 'w', '', 0, function('InComment'))
+ call assert_equal('Another Text for VIM', getline('.'))
+
+ 1
+ call search('VIM', 'w', '', 0, function('InString'))
+ call assert_equal(' let a = "VIM"', getline('.'))
+
+ delfunc InComment
+ delfunc InString
+ bwipe!
+endfunc
+
func Test_syn_include_contains_TOP()
let l:case = "TOP in included syntax means its group list name"
new
diff --git a/src/nvim/testdir/test_winbuf_close.vim b/src/nvim/testdir/test_winbuf_close.vim
index 7f5b80e8d3..f4878c2397 100644
--- a/src/nvim/testdir/test_winbuf_close.vim
+++ b/src/nvim/testdir/test_winbuf_close.vim
@@ -194,3 +194,22 @@ func Test_tabwin_close()
call assert_true(v:true)
%bwipe!
endfunc
+
+" Test when closing a split window (above/below) restores space to the window
+" below when 'noequalalways' and 'splitright' are set.
+func Test_window_close_splitright_noequalalways()
+ set noequalalways
+ set splitright
+ new
+ let w1 = win_getid()
+ new
+ let w2 = win_getid()
+ execute "normal \<c-w>b"
+ let h = winheight(0)
+ let w = win_getid()
+ new
+ q
+ call assert_equal(h, winheight(0), "Window height does not match eight before opening and closing another window")
+ call assert_equal(w, win_getid(), "Did not return to original window after opening and closing a window")
+endfunc
+
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 4861b71995..e09af7a7bb 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3079,9 +3079,21 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp)
return frp->fr_prev;
}
+ // By default the next window will get the space that was abandoned by this
+ // window
frame_T *target_fr = frp->fr_next;
frame_T *other_fr = frp->fr_prev;
- if (p_spr || p_sb) {
+
+ // If this is part of a column of windows and 'splitbelow' is true then the
+ // previous window will get the space.
+ if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_COL && p_sb) {
+ target_fr = frp->fr_prev;
+ other_fr = frp->fr_next;
+ }
+
+ // If this is part of a row of windows, and 'splitright' is true then the
+ // previous window will get the space.
+ if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW && p_spr) {
target_fr = frp->fr_prev;
other_fr = frp->fr_next;
}
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index a74da6073a..46a3798dc4 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -195,10 +195,12 @@ describe("API: set highlight", function()
reverse = true,
undercurl = true,
underline = true,
+ strikethrough = true,
cterm = {
italic = true,
reverse = true,
undercurl = true,
+ strikethrough = true,
}
}
local highlight3_result_gui = {
@@ -209,6 +211,7 @@ describe("API: set highlight", function()
reverse = true,
undercurl = true,
underline = true,
+ strikethrough = true,
}
local highlight3_result_cterm = {
background = highlight_color.ctermbg,
@@ -216,6 +219,7 @@ describe("API: set highlight", function()
italic = true,
reverse = true,
undercurl = true,
+ strikethrough = true,
}
local function get_ns()
@@ -264,7 +268,7 @@ describe("API: set highlight", function()
exec_capture('highlight Test_hl'))
meths.set_hl(0, 'Test_hl2', highlight3_config)
- eq('Test_hl2 xxx cterm=undercurl,italic,reverse ctermfg=8 ctermbg=15 gui=bold,underline,undercurl,italic,reverse guifg=#ff0000 guibg=#0032aa',
+ eq('Test_hl2 xxx cterm=undercurl,italic,reverse,strikethrough ctermfg=8 ctermbg=15 gui=bold,underline,undercurl,italic,reverse,strikethrough guifg=#ff0000 guibg=#0032aa',
exec_capture('highlight Test_hl2'))
-- Colors are stored exactly as they are defined.