aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/optwin.vim4
-rwxr-xr-xscripts/vim-patch.sh55
-rw-r--r--src/nvim/assert.h9
-rw-r--r--src/nvim/ex_cmds.c15
-rw-r--r--src/nvim/globals.h1
-rw-r--r--src/nvim/msgpack_rpc/remote_ui.c12
-rw-r--r--src/nvim/quickfix.c3
-rw-r--r--src/nvim/screen.c54
-rw-r--r--src/nvim/syntax.c66
-rw-r--r--src/nvim/syntax_defs.h4
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/test_breakindent.in123
-rw-r--r--src/nvim/testdir/test_breakindent.ok74
-rw-r--r--src/nvim/tui/tui.c6
-rw-r--r--src/nvim/ugrid.h2
-rw-r--r--src/nvim/ui.c7
-rw-r--r--src/nvim/ui.h3
-rw-r--r--src/nvim/ui_bridge.c11
-rw-r--r--src/nvim/version.c4
-rw-r--r--test/functional/legacy/breakindent_spec.lua211
-rw-r--r--test/functional/terminal/highlight_spec.lua6
-rw-r--r--test/functional/ui/highlight_spec.lua310
-rw-r--r--test/functional/ui/mouse_spec.lua17
-rw-r--r--test/functional/ui/screen.lua9
24 files changed, 717 insertions, 290 deletions
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 07dcd31b1b..68444dde01 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -766,7 +766,7 @@ call append("$", "infercase\tadjust case of a keyword completion match")
call append("$", "\t(local to buffer)")
call <SID>BinOptionL("inf")
if has("digraphs")
- call append("$", "digraph\tenable entering digraps with c1 <BS> c2")
+ call append("$", "digraph\tenable entering digraphs with c1 <BS> c2")
call <SID>BinOptionG("dg", &dg)
endif
call append("$", "tildeop\tthe \"~\" command behaves like an operator")
@@ -1142,7 +1142,7 @@ if has("arabic")
call <SID>BinOptionG("tbidi", &tbidi)
endif
if has("keymap")
- call append("$", "keymap\tname of a keyboard mappping")
+ call append("$", "keymap\tname of a keyboard mapping")
call <SID>OptionL("kmp")
endif
if has("langmap")
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index 751f50d290..7a0001769a 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -33,7 +33,11 @@ usage() {
# Checks if a program is in the user's PATH, and is executable.
check_executable() {
- if [[ ! -x $(command -v "${1}") ]]; then
+ test -x "$(command -v "${1}")"
+}
+
+require_executable() {
+ if ! check_executable "${1}"; then
>&2 echo "${BASENAME}: '${1}' not found in PATH or not executable."
exit 1
fi
@@ -61,7 +65,7 @@ clean_files() {
}
get_vim_sources() {
- check_executable git
+ require_executable git
if [[ ! -d ${VIM_SOURCE_DIR} ]]; then
echo "Cloning Vim sources into '${VIM_SOURCE_DIR}'."
@@ -194,9 +198,28 @@ get_vim_patch() {
echo " for more information."
}
+hub_pr() {
+ hub pull-request -m "$1"
+}
+
+git_hub_pr() {
+ git hub pull new -m "$1"
+}
+
submit_pr() {
- check_executable git
- check_executable hub
+ require_executable git
+ local push_first
+ push_first=1
+ local submit_fn
+ if check_executable hub; then
+ submit_fn="hub_pr"
+ elif check_executable git-hub; then
+ push_first=0
+ submit_fn="git_hub_pr"
+ else
+ >&2 echo "${BASENAME}: 'hub' or 'git-hub' not found in PATH or not executable."
+ exit 1
+ fi
cd "${NEOVIM_SOURCE_DIR}"
local checked_out_branch
@@ -219,14 +242,17 @@ submit_pr() {
local pr_message
pr_message="$(printf '[RFC] vim-patch:%s\n\n%s\n' "${pr_title#,}" "${pr_body}")"
- echo "Pushing to 'origin/${checked_out_branch}'."
- output="$(git push origin "${checked_out_branch}" 2>&1)" &&
- echo "✔ ${output}" ||
- (echo "✘ ${output}"; git reset --soft HEAD^1; false)
+ if [[ $push_first -ne 0 ]]; then
+ echo "Pushing to 'origin/${checked_out_branch}'."
+ output="$(git push origin "${checked_out_branch}" 2>&1)" &&
+ echo "✔ ${output}" ||
+ (echo "✘ ${output}"; git reset --soft HEAD^1; false)
+
+ echo
+ fi
- echo
echo "Creating pull request."
- output="$(hub pull-request -F - 2>&1 <<< "${pr_message}")" &&
+ output="$(${submit_fn} "${pr_message}" 2>&1)" &&
echo "✔ ${output}" ||
(echo "✘ ${output}"; false)
@@ -264,6 +290,9 @@ list_vim_patches() {
is_missing="$(sed -n '/static int included_patches/,/}/p' "${NEOVIM_SOURCE_DIR}/src/nvim/version.c" |
grep -x -e "[[:space:]]*//[[:space:]]${patch_number} NA.*" -e "[[:space:]]*${patch_number}," >/dev/null && echo "false" || echo "true")"
vim_commit="${vim_tag#v}"
+ if (cd "${VIM_SOURCE_DIR}" && git show --name-only "v${vim_commit}" 2>/dev/null) | grep -q ^runtime; then
+ vim_commit="${vim_commit} (+runtime)"
+ fi
else
# Untagged Vim patch (e.g. runtime updates), check the Neovim git log:
is_missing="$(cd "${NEOVIM_SOURCE_DIR}" &&
@@ -346,9 +375,9 @@ review_commit() {
}
review_pr() {
- check_executable curl
- check_executable nvim
- check_executable jq
+ require_executable curl
+ require_executable nvim
+ require_executable jq
get_vim_sources
diff --git a/src/nvim/assert.h b/src/nvim/assert.h
index 2c43777858..761636305e 100644
--- a/src/nvim/assert.h
+++ b/src/nvim/assert.h
@@ -65,9 +65,16 @@
# define STATIC_ASSERT_STATEMENT(cond, msg) _Static_assert(cond, msg)
# undef STATIC_ASSERT_PRAGMA_START
+
+#if __GNUC__ >= 6
# define STATIC_ASSERT_PRAGMA_START \
_Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-pedantic\"") \
+ _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
+#else
+# define STATIC_ASSERT_PRAGMA_START \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-pedantic\"")
+#endif
# undef STATIC_ASSERT_PRAGMA_END
# define STATIC_ASSERT_PRAGMA_END \
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 415d6ee460..86f1a16216 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -3816,16 +3816,17 @@ skip:
EMSG2(_(e_patnotf2), get_search_pat());
}
- if (do_ask && hasAnyFolding(curwin))
- /* Cursor position may require updating */
+ if (do_ask && hasAnyFolding(curwin)) {
+ // Cursor position may require updating
changed_window_setting();
+ }
- vim_regfree(regmatch.regprog);
+ vim_regfree(regmatch.regprog);
- // Restore the flag values, they can be used for ":&&".
- do_all = save_do_all;
- do_ask = save_do_ask;
- }
+ // Restore the flag values, they can be used for ":&&".
+ do_all = save_do_all;
+ do_ask = save_do_ask;
+}
/*
* Give message for number of substitutions.
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 30fe97c8db..dafb75ca87 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -504,6 +504,7 @@ EXTERN int cterm_normal_fg_bold INIT(= 0);
EXTERN int cterm_normal_bg_color INIT(= 0);
EXTERN RgbValue normal_fg INIT(= -1);
EXTERN RgbValue normal_bg INIT(= -1);
+EXTERN RgbValue normal_sp INIT(= -1);
EXTERN int autocmd_busy INIT(= FALSE); /* Is apply_autocmds() busy? */
EXTERN int autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
diff --git a/src/nvim/msgpack_rpc/remote_ui.c b/src/nvim/msgpack_rpc/remote_ui.c
index f0d92b52a0..6ffcffe2e1 100644
--- a/src/nvim/msgpack_rpc/remote_ui.c
+++ b/src/nvim/msgpack_rpc/remote_ui.c
@@ -96,6 +96,7 @@ static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
ui->visual_bell = remote_ui_visual_bell;
ui->update_fg = remote_ui_update_fg;
ui->update_bg = remote_ui_update_bg;
+ ui->update_sp = remote_ui_update_sp;
ui->flush = remote_ui_flush;
ui->suspend = remote_ui_suspend;
ui->set_title = remote_ui_set_title;
@@ -285,6 +286,10 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
PUT(hl, "background", INTEGER_OBJ(attrs.background));
}
+ if (attrs.special != -1) {
+ PUT(hl, "special", INTEGER_OBJ(attrs.special));
+ }
+
ADD(args, DICTIONARY_OBJ(hl));
push_call(ui, "highlight_set", args);
}
@@ -323,6 +328,13 @@ static void remote_ui_update_bg(UI *ui, int bg)
push_call(ui, "update_bg", args);
}
+static void remote_ui_update_sp(UI *ui, int sp)
+{
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(sp));
+ push_call(ui, "update_sp", args);
+}
+
static void remote_ui_flush(UI *ui)
{
UIData *data = ui->data;
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 17cb8a86aa..151b9d3790 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -160,9 +160,6 @@ qf_init (
{
qf_info_T *qi = &ql_info;
- if (efile == NULL)
- return FAIL;
-
if (wp != NULL) {
qi = ll_get_or_alloc_list(wp);
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 10b5b6bba4..34eef83164 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -3385,11 +3385,9 @@ win_line (
&& lcs_nbsp)
|| (c == ' ' && lcs_space && ptr - line <= trailcol))) {
c = (c == ' ') ? lcs_space : lcs_nbsp;
- if (area_attr == 0 && search_attr == 0) {
- n_attr = 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; // save current attr
- }
+ n_attr = 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = true;
@@ -3402,11 +3400,9 @@ win_line (
if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') {
c = lcs_trail;
- if (!attr_pri) {
- n_attr = 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
- }
+ n_attr = 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3554,11 +3550,9 @@ win_line (
c = ' ';
}
lcs_eol_one = -1;
- --ptr; /* put it back at the NUL */
- if (!attr_pri) {
- extra_attr = hl_attr(HLF_AT);
- n_attr = 1;
- }
+ ptr--; // put it back at the NUL
+ extra_attr = hl_attr(HLF_AT);
+ n_attr = 1;
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3587,12 +3581,10 @@ win_line (
n_extra = byte2cells(c) - 1;
c = *p_extra++;
}
- if (!attr_pri) {
- n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
- }
- mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ n_attr = n_extra + 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; // save current attr
+ mb_utf8 = false; // don't draw as UTF-8
} else if (VIsual_active
&& (VIsual_mode == Ctrl_V
|| VIsual_mode == 'v')
@@ -3702,11 +3694,10 @@ win_line (
did_wcol = true;
}
- /* Don't override visual selection highlighting. */
- if (n_attr > 0
- && draw_state == WL_LINE
- && !attr_pri)
- char_attr = extra_attr;
+ // Don't override visual selection highlighting.
+ if (n_attr > 0 && draw_state == WL_LINE) {
+ char_attr = hl_combine_attr(char_attr, extra_attr);
+ }
/*
* Handle the case where we are in column 0 but not on the first
@@ -3734,13 +3725,12 @@ win_line (
mb_utf8 = TRUE;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE; /* don't draw as UTF-8 */
- if (!attr_pri) {
- saved_attr3 = char_attr; /* save current attr */
- char_attr = hl_attr(HLF_AT); /* later copied to char_attr */
- n_attr3 = 1;
+ } else {
+ mb_utf8 = false; // don't draw as UTF-8
}
+ saved_attr3 = char_attr; // save current attr
+ char_attr = hl_attr(HLF_AT); // later copied to char_attr
+ n_attr3 = 1;
}
/*
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 765207928a..9a5484704e 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -62,8 +62,10 @@ struct hl_group {
int sg_gui; // "gui=" highlighting attributes
RgbValue sg_rgb_fg; // RGB foreground color
RgbValue sg_rgb_bg; // RGB background color
+ RgbValue sg_rgb_sp; // RGB special color
uint8_t *sg_rgb_fg_name; // RGB foreground color name
uint8_t *sg_rgb_bg_name; // RGB background color name
+ uint8_t *sg_rgb_sp_name; // RGB special color name
};
#define SG_CTERM 2 // cterm has been set
@@ -6169,12 +6171,11 @@ do_highlight (
break;
}
- /*
- * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
- * "guibg").
- */
- while (*linep && !ascii_iswhite(*linep) && *linep != '=')
- ++linep;
+ // Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg",
+ // "guibg" or "guisp").
+ while (*linep && !ascii_iswhite(*linep) && *linep != '=') {
+ linep++;
+ }
xfree(key);
key = vim_strnsave_up(key_start, (int)(linep - key_start));
linep = skipwhite(linep);
@@ -6452,7 +6453,23 @@ do_highlight (
normal_bg = HL_TABLE()[idx].sg_rgb_bg;
}
} else if (STRCMP(key, "GUISP") == 0) {
- // Ignored for now
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ xfree(HL_TABLE()[idx].sg_rgb_sp_name);
+ if (STRCMP(arg, "NONE") != 0) {
+ HL_TABLE()[idx].sg_rgb_sp_name = (uint8_t *)xstrdup((char *)arg);
+ HL_TABLE()[idx].sg_rgb_sp = name_to_color(arg);
+ } else {
+ HL_TABLE()[idx].sg_rgb_sp_name = NULL;
+ HL_TABLE()[idx].sg_rgb_sp = -1;
+ }
+ }
+
+ if (is_normal_group) {
+ normal_sp = HL_TABLE()[idx].sg_rgb_sp;
+ }
} else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) {
// Ignored for now
} else {
@@ -6516,6 +6533,7 @@ void restore_cterm_colors(void)
{
normal_fg = -1;
normal_bg = -1;
+ normal_sp = -1;
cterm_normal_fg_color = 0;
cterm_normal_fg_bold = 0;
cterm_normal_bg_color = 0;
@@ -6532,6 +6550,7 @@ static int hl_has_settings(int idx, int check_link)
|| HL_TABLE()[idx].sg_cterm_bg != 0
|| HL_TABLE()[idx].sg_rgb_fg_name != NULL
|| HL_TABLE()[idx].sg_rgb_bg_name != NULL
+ || HL_TABLE()[idx].sg_rgb_sp_name != NULL
|| (check_link && (HL_TABLE()[idx].sg_set & SG_LINK));
}
@@ -6548,14 +6567,18 @@ static void highlight_clear(int idx)
HL_TABLE()[idx].sg_gui = 0;
HL_TABLE()[idx].sg_rgb_fg = -1;
HL_TABLE()[idx].sg_rgb_bg = -1;
+ HL_TABLE()[idx].sg_rgb_sp = -1;
xfree(HL_TABLE()[idx].sg_rgb_fg_name);
HL_TABLE()[idx].sg_rgb_fg_name = NULL;
xfree(HL_TABLE()[idx].sg_rgb_bg_name);
HL_TABLE()[idx].sg_rgb_bg_name = NULL;
- /* Clear the script ID only when there is no link, since that is not
- * cleared. */
- if (HL_TABLE()[idx].sg_link == 0)
+ xfree(HL_TABLE()[idx].sg_rgb_sp_name);
+ HL_TABLE()[idx].sg_rgb_sp_name = NULL;
+ // Clear the script ID only when there is no link, since that is not
+ // cleared.
+ if (HL_TABLE()[idx].sg_link == 0) {
HL_TABLE()[idx].sg_scriptID = 0;
+ }
}
@@ -6597,7 +6620,8 @@ int get_attr_entry(attrentry_T *aep)
&& aep->cterm_bg_color == taep->cterm_bg_color
&& aep->rgb_ae_attr == taep->rgb_ae_attr
&& aep->rgb_fg_color == taep->rgb_fg_color
- && aep->rgb_bg_color == taep->rgb_bg_color) {
+ && aep->rgb_bg_color == taep->rgb_bg_color
+ && aep->rgb_sp_color == taep->rgb_sp_color) {
return i + ATTR_OFF;
}
}
@@ -6635,6 +6659,7 @@ int get_attr_entry(attrentry_T *aep)
taep->rgb_ae_attr = aep->rgb_ae_attr;
taep->rgb_fg_color = aep->rgb_fg_color;
taep->rgb_bg_color = aep->rgb_bg_color;
+ taep->rgb_sp_color = aep->rgb_sp_color;
return table->ga_len - 1 + ATTR_OFF;
}
@@ -6696,6 +6721,10 @@ int hl_combine_attr(int char_attr, int prim_attr)
if (spell_aep->rgb_bg_color >= 0) {
new_en.rgb_bg_color = spell_aep->rgb_bg_color;
}
+
+ if (spell_aep->rgb_sp_color >= 0) {
+ new_en.rgb_sp_color = spell_aep->rgb_sp_color;
+ }
}
return get_attr_entry(&new_en);
}
@@ -6733,7 +6762,7 @@ static void highlight_list_one(int id)
didh = highlight_list_arg(id, didh, LIST_STRING,
0, sgp->sg_rgb_bg_name, "guibg");
didh = highlight_list_arg(id, didh, LIST_STRING,
- 0, NULL, "guisp");
+ 0, sgp->sg_rgb_sp_name, "guisp");
if (sgp->sg_link && !got_int) {
(void)syn_list_header(didh, 9999, id);
@@ -6847,8 +6876,9 @@ highlight_color (
if (modec == 'g') {
if (fg)
return HL_TABLE()[id - 1].sg_rgb_fg_name;
- if (sp)
- return NULL;
+ if (sp) {
+ return HL_TABLE()[id - 1].sg_rgb_sp_name;
+ }
return HL_TABLE()[id - 1].sg_rgb_bg_name;
}
if (font || sp)
@@ -6935,10 +6965,12 @@ set_hl_attr (
// before setting attr_entry->{f,g}g_color to a other than -1
at_en.rgb_fg_color = sgp->sg_rgb_fg_name ? sgp->sg_rgb_fg : -1;
at_en.rgb_bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1;
+ at_en.rgb_sp_color = sgp->sg_rgb_sp_name ? sgp->sg_rgb_sp : -1;
if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0
|| at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1
- || at_en.cterm_ae_attr != 0 || at_en.rgb_ae_attr != 0) {
+ || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0
+ || at_en.rgb_ae_attr != 0) {
sgp->sg_attr = get_attr_entry(&at_en);
}
}
@@ -7271,6 +7303,10 @@ int highlight_changed(void)
hlt[hlcnt + i].sg_rgb_bg = hlt[id - 1].sg_rgb_bg;
}
+ if (hlt[id - 1].sg_rgb_sp != hlt[id_S - 1].sg_rgb_sp) {
+ hlt[hlcnt + i].sg_rgb_sp = hlt[id - 1].sg_rgb_sp;
+ }
+
highlight_ga.ga_len = hlcnt + i + 1;
set_hl_attr(hlcnt + i); /* At long last we can apply */
highlight_stlnc[i] = syn_id2attr(hlcnt + i + 1);
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index 67cf672ef2..8d207e6286 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -69,8 +69,8 @@ struct syn_state {
// Structure shared between syntax.c, screen.c
typedef struct attr_entry {
- short rgb_ae_attr, cterm_ae_attr; // HL_BOLD, etc.
- RgbValue rgb_fg_color, rgb_bg_color;
+ int16_t rgb_ae_attr, cterm_ae_attr; // HL_BOLD, etc.
+ RgbValue rgb_fg_color, rgb_bg_color, rgb_sp_color;
int cterm_fg_color, cterm_bg_color;
} attrentry_T;
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 0e3149b912..90542a6a6c 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -32,7 +32,6 @@ SCRIPTS := \
test73.out \
test79.out \
test_listlbr.out \
- test_breakindent.out \
test_close_count.out \
test_marks.out \
diff --git a/src/nvim/testdir/test_breakindent.in b/src/nvim/testdir/test_breakindent.in
deleted file mode 100644
index 5a8e580c4a..0000000000
--- a/src/nvim/testdir/test_breakindent.in
+++ /dev/null
@@ -1,123 +0,0 @@
-Test for breakindent
-
-STARTTEST
-:so small.vim
-:if !exists("+breakindent") | e! test.ok | w! test.out | qa! | endif
-:set wildchar=^E
-:10new|:vsp|:vert resize 20
-:put =\"\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\"
-:set ts=4 sw=4 sts=4 breakindent
-:fu! ScreenChar(line, width)
-: let c=''
-: for i in range(1,a:width)
-: let c.=nr2char(screenchar(a:line, i))
-: endfor
-: let c.="\n"
-: for i in range(1,a:width)
-: let c.=nr2char(screenchar(a:line+1, i))
-: endfor
-: let c.="\n"
-: for i in range(1,a:width)
-: let c.=nr2char(screenchar(a:line+2, i))
-: endfor
-: return c
-:endfu
-:fu DoRecordScreen()
-: wincmd l
-: $put =printf(\"\n%s\", g:test)
-: $put =g:line1
-: wincmd p
-:endfu
-:set briopt=min:0
-:let g:test="Test 1: Simple breakindent"
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test="Test 2: Simple breakindent + sbr=>>"
-:set sbr=>>
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test ="Test 3: Simple breakindent + briopt:sbr"
-:set briopt=sbr,min:0 sbr=++
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test ="Test 4: Simple breakindent + min width: 18"
-:set sbr= briopt=min:18
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test =" Test 5: Simple breakindent + shift by 2"
-:set briopt=shift:2,min:0
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test=" Test 6: Simple breakindent + shift by -1"
-:set briopt=shift:-1,min:0
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:let g:test=" Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr"
-:set briopt=shift:1,sbr,min:0 nu sbr=? nuw=4
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:let g:test=" Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr"
-:set briopt=shift:1,sbr,min:0 nu sbr=# list lcs&vi
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:let g:test=" Test 9: breakindent + shift by +1 + 'nu' + sbr=# list"
-:set briopt-=sbr
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:let g:test=" Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n"
-:set cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0
-:let line1=ScreenChar(line('.'),10)
-:call DoRecordScreen()
-:wincmd p
-:let g:test="\n Test 11: strdisplaywidth when breakindent is on"
-:set cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4
-:let text=getline(2) "skip leading tab when calculating text width
-:let width = strlen(text[1:])+indent(2)*4+strlen(&sbr)*3 " text wraps 3 times
-:$put =g:test
-:$put =printf(\"strdisplaywidth: %d == calculated: %d\", strdisplaywidth(text), width)
-:let g:str="\t\t\t\t\t{"
-:let g:test=" Test 12: breakindent + long indent"
-:wincmd p
-:set all& breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4
-:$put =g:str
-zt:let line1=ScreenChar(1,10)
-:wincmd p
-:call DoRecordScreen()
-:"
-:" Test, that the string " a\tb\tc\td\te" is correctly
-:" displayed in a 20 column wide window (see bug report
-:" https://groups.google.com/d/msg/vim_dev/ZOdg2mc9c9Y/TT8EhFjEy0IJ
-:only
-:vert 20new
-:set all& breakindent briopt=min:10
-:call setline(1, [" a\tb\tc\td\te", " z y x w v"])
-:/^\s*a
-fbgjyl:let line1 = @0
-:?^\s*z
-fygjyl:let line2 = @0
-:quit!
-:$put ='Test 13: breakindent with wrapping Tab'
-:$put =line1
-:$put =line2
-:"
-:let g:test="Test 14: breakindent + visual blockwise delete #1"
-:set all& breakindent shada+=nX-test-breakindent.shada
-:30vnew
-:normal! 3a1234567890
-:normal! a abcde
-:exec "normal! 0\<C-V>tex"
-:let line1=ScreenChar(line('.'),8)
-:call DoRecordScreen()
-:"
-:let g:test="Test 15: breakindent + visual blockwise delete #2"
-:%d
-:normal! 4a1234567890
-:exec "normal! >>\<C-V>3f0x"
-:let line1=ScreenChar(line('.'),20)
-:call DoRecordScreen()
-:quit!
-:"
-:%w! test.out
-:qa!
-ENDTEST
-dummy text
diff --git a/src/nvim/testdir/test_breakindent.ok b/src/nvim/testdir/test_breakindent.ok
deleted file mode 100644
index 995bd5f29c..0000000000
--- a/src/nvim/testdir/test_breakindent.ok
+++ /dev/null
@@ -1,74 +0,0 @@
-
- abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP
-
-Test 1: Simple breakindent
- abcd
- qrst
- GHIJ
-
-Test 2: Simple breakindent + sbr=>>
- abcd
- >>qr
- >>EF
-
-Test 3: Simple breakindent + briopt:sbr
- abcd
-++ qrst
-++ GHIJ
-
-Test 4: Simple breakindent + min width: 18
- abcd
- qrstuv
- IJKLMN
-
- Test 5: Simple breakindent + shift by 2
- abcd
- qr
- EF
-
- Test 6: Simple breakindent + shift by -1
- abcd
- qrstu
- HIJKL
-
- Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr
- 2 ab
- ? m
- ? x
-
- Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr
- 2 ^Iabcd
- # opq
- # BCD
-
- Test 9: breakindent + shift by +1 + 'nu' + sbr=# list
- 2 ^Iabcd
- #op
- #AB
-
- Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n
- 2 ab
-~ mn
-~ yz
-
- Test 11: strdisplaywidth when breakindent is on
-strdisplaywidth: 46 == calculated: 64
- {
-
- Test 12: breakindent + long indent
-56
-
-~
-Test 13: breakindent with wrapping Tab
-d
-w
-
-Test 14: breakindent + visual blockwise delete #1
-e
-~
-~
-
-Test 15: breakindent + visual blockwise delete #2
- 1234567890
-~
-~
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 202c5666a1..62bc81ba64 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -100,6 +100,7 @@ UI *tui_start(void)
ui->visual_bell = tui_visual_bell;
ui->update_fg = tui_update_fg;
ui->update_bg = tui_update_bg;
+ ui->update_sp = tui_update_sp;
ui->flush = tui_flush;
ui->suspend = tui_suspend;
ui->set_title = tui_set_title;
@@ -573,6 +574,11 @@ static void tui_update_bg(UI *ui, int bg)
((TUIData *)ui->data)->grid.bg = bg;
}
+static void tui_update_sp(UI *ui, int sp)
+{
+ // Do nothing; 'special' color is for GUI only
+}
+
static void tui_flush(UI *ui)
{
TUIData *data = ui->data;
diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h
index df51e1fced..ad6d96a168 100644
--- a/src/nvim/ugrid.h
+++ b/src/nvim/ugrid.h
@@ -21,7 +21,7 @@ struct ugrid {
UCell **cells;
};
-#define EMPTY_ATTRS ((HlAttrs){false, false, false, false, false, -1, -1})
+#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 })
#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \
do { \
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index d32969f149..05322a6f64 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -155,6 +155,7 @@ void ui_resize(int new_width, int new_height)
UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1));
UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1));
+ UI_CALL(update_sp, (ui->rgb ? normal_sp : -1));
sr.top = 0;
sr.bot = height - 1;
@@ -388,7 +389,7 @@ static void parse_control_character(uint8_t c)
static void set_highlight_args(int attr_code)
{
- HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1 };
+ HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1, -1 };
HlAttrs cterm_attrs = rgb_attrs;
if (attr_code == HL_NORMAL) {
@@ -425,6 +426,10 @@ static void set_highlight_args(int attr_code)
rgb_attrs.background = aep->rgb_bg_color;
}
+ if (aep->rgb_sp_color != normal_sp) {
+ rgb_attrs.special = aep->rgb_sp_color;
+ }
+
if (cterm_normal_fg_color != aep->cterm_fg_color) {
cterm_attrs.foreground = aep->cterm_fg_color - 1;
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index 4c051fcfbf..5934d2fee9 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -7,7 +7,7 @@
typedef struct {
bool bold, underline, undercurl, italic, reverse;
- int foreground, background;
+ int foreground, background, special;
} HlAttrs;
typedef struct ui_t UI;
@@ -35,6 +35,7 @@ struct ui_t {
void (*flush)(UI *ui);
void (*update_fg)(UI *ui, int fg);
void (*update_bg)(UI *ui, int bg);
+ void (*update_sp)(UI *ui, int sp);
void (*suspend)(UI *ui);
void (*set_title)(UI *ui, char *title);
void (*set_icon)(UI *ui, char *icon);
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 359fffe3bf..fd9d4671e3 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -49,6 +49,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
rv->bridge.visual_bell = ui_bridge_visual_bell;
rv->bridge.update_fg = ui_bridge_update_fg;
rv->bridge.update_bg = ui_bridge_update_bg;
+ rv->bridge.update_sp = ui_bridge_update_sp;
rv->bridge.flush = ui_bridge_flush;
rv->bridge.suspend = ui_bridge_suspend;
rv->bridge.set_title = ui_bridge_set_title;
@@ -305,6 +306,16 @@ static void ui_bridge_update_bg_event(void **argv)
ui->update_bg(ui, PTR2INT(argv[1]));
}
+static void ui_bridge_update_sp(UI *b, int sp)
+{
+ UI_CALL(b, update_sp, 2, b, INT2PTR(sp));
+}
+static void ui_bridge_update_sp_event(void **argv)
+{
+ UI *ui = UI(argv[0]);
+ ui->update_sp(ui, PTR2INT(argv[1]));
+}
+
static void ui_bridge_flush(UI *b)
{
UI_CALL(b, flush, 1, b);
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 56ede1aa78..82a15f9833 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -625,9 +625,9 @@ static int included_patches[] = {
// 1062 NA
// 1061,
// 1060 NA
- // 1059,
+ 1059,
// 1058,
- // 1057,
+ 1057,
// 1056,
1055,
1054,
diff --git a/test/functional/legacy/breakindent_spec.lua b/test/functional/legacy/breakindent_spec.lua
new file mode 100644
index 0000000000..a12d4add10
--- /dev/null
+++ b/test/functional/legacy/breakindent_spec.lua
@@ -0,0 +1,211 @@
+-- Test for breakindent
+
+local helpers = require('test.functional.helpers')
+local feed, insert = helpers.feed, helpers.insert
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('breakindent', function()
+ setup(clear)
+
+ it('is working', function()
+ insert('dummy text')
+
+ execute('set wildchar=^E')
+ execute('10new')
+ execute('vsp')
+ execute('vert resize 20')
+ execute([[put =\"\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\"]])
+ execute('set ts=4 sw=4 sts=4 breakindent')
+ execute('fu! ScreenChar(line, width)')
+ execute(' let c=""')
+ execute(' for i in range(1,a:width)')
+ execute(' let c.=nr2char(screenchar(a:line, i))')
+ execute(' endfor')
+ execute([[ let c.="\n"]])
+ execute(' for i in range(1,a:width)')
+ execute(' let c.=nr2char(screenchar(a:line+1, i))')
+ execute(' endfor')
+ execute([[ let c.="\n"]])
+ execute(' for i in range(1,a:width)')
+ execute(' let c.=nr2char(screenchar(a:line+2, i))')
+ execute(' endfor')
+ execute(' return c')
+ execute('endfu')
+ execute('fu DoRecordScreen()')
+ execute(' wincmd l')
+ execute([[ $put =printf(\"\n%s\", g:test)]])
+ execute(' $put =g:line1')
+ execute(' wincmd p')
+ execute('endfu')
+ execute('set briopt=min:0')
+ execute('let g:test="Test 1: Simple breakindent"')
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+ execute('let g:test="Test 2: Simple breakindent + sbr=>>"')
+ execute('set sbr=>>')
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+ execute('let g:test ="Test 3: Simple breakindent + briopt:sbr"')
+ execute('set briopt=sbr,min:0 sbr=++')
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+ execute('let g:test ="Test 4: Simple breakindent + min width: 18"')
+ execute('set sbr= briopt=min:18')
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+ execute('let g:test =" Test 5: Simple breakindent + shift by 2"')
+ execute('set briopt=shift:2,min:0')
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+ execute('let g:test=" Test 6: Simple breakindent + shift by -1"')
+ execute('set briopt=shift:-1,min:0')
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+ execute('let g:test=" Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr"')
+ execute('set briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
+ execute('let line1=ScreenChar(line("."),10)')
+ execute('call DoRecordScreen()')
+ execute('let g:test=" Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr"')
+ execute('set briopt=shift:1,sbr,min:0 nu sbr=# list lcs&vi')
+ execute('let line1=ScreenChar(line("."),10)')
+ execute('call DoRecordScreen()')
+ execute([[let g:test=" Test 9: breakindent + shift by +1 + 'nu' + sbr=# list"]])
+ execute('set briopt-=sbr')
+ execute('let line1=ScreenChar(line("."),10)')
+ execute('call DoRecordScreen()')
+ execute([[let g:test=" Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n"]])
+ execute('set cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
+ execute('let line1=ScreenChar(line("."),10)')
+ execute('call DoRecordScreen()')
+ execute('wincmd p')
+ execute([[let g:test="\n Test 11: strdisplaywidth when breakindent is on"]])
+ execute('set cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
+ -- Skip leading tab when calculating text width.
+ execute('let text=getline(2)')
+ -- Text wraps 3 times.
+ execute('let width = strlen(text[1:])+indent(2)*4+strlen(&sbr)*3')
+ execute('$put =g:test')
+ execute([[$put =printf(\"strdisplaywidth: %d == calculated: %d\", strdisplaywidth(text), width)]])
+ execute([[let g:str="\t\t\t\t\t{"]])
+ execute('let g:test=" Test 12: breakindent + long indent"')
+ execute('wincmd p')
+ execute('set all& breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4')
+ execute('$put =g:str')
+ feed('zt')
+ execute('let line1=ScreenChar(1,10)')
+ execute('wincmd p')
+ execute('call DoRecordScreen()')
+
+ -- Test, that the string " a\tb\tc\td\te" is correctly displayed in a
+ -- 20 column wide window (see bug report
+ -- https://groups.google.com/d/msg/vim_dev/ZOdg2mc9c9Y/TT8EhFjEy0IJ ).
+ execute('only')
+ execute('vert 20new')
+ execute('set all& breakindent briopt=min:10')
+ execute([[call setline(1, [" a\tb\tc\td\te", " z y x w v"])]])
+ execute([[/^\s*a]])
+ feed('fbgjyl')
+ execute('let line1 = @0')
+ execute([[?^\s*z]])
+ feed('fygjyl')
+ execute('let line2 = @0')
+ execute('quit!')
+ execute([[$put ='Test 13: breakindent with wrapping Tab']])
+ execute('$put =line1')
+ execute('$put =line2')
+
+ execute('let g:test="Test 14: breakindent + visual blockwise delete #1"')
+ execute('set all& breakindent shada+=nX-test-breakindent.shada')
+ execute('30vnew')
+ execute('normal! 3a1234567890')
+ execute('normal! a abcde')
+ execute([[exec "normal! 0\<C-V>tex"]])
+ execute('let line1=ScreenChar(line("."),8)')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test="Test 15: breakindent + visual blockwise delete #2"')
+ execute('%d')
+ execute('normal! 4a1234567890')
+ execute([[exec "normal! >>\<C-V>3f0x"]])
+ execute('let line1=ScreenChar(line("."),20)')
+ execute('call DoRecordScreen()')
+ execute('quit!')
+
+ -- Assert buffer contents.
+ expect([[
+
+ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP
+
+ Test 1: Simple breakindent
+ abcd
+ qrst
+ GHIJ
+
+ Test 2: Simple breakindent + sbr=>>
+ abcd
+ >>qr
+ >>EF
+
+ Test 3: Simple breakindent + briopt:sbr
+ abcd
+ ++ qrst
+ ++ GHIJ
+
+ Test 4: Simple breakindent + min width: 18
+ abcd
+ qrstuv
+ IJKLMN
+
+ Test 5: Simple breakindent + shift by 2
+ abcd
+ qr
+ EF
+
+ Test 6: Simple breakindent + shift by -1
+ abcd
+ qrstu
+ HIJKL
+
+ Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr
+ 2 ab
+ ? m
+ ? x
+
+ Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr
+ 2 ^Iabcd
+ # opq
+ # BCD
+
+ Test 9: breakindent + shift by +1 + 'nu' + sbr=# list
+ 2 ^Iabcd
+ #op
+ #AB
+
+ Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n
+ 2 ab
+ ~ mn
+ ~ yz
+
+ Test 11: strdisplaywidth when breakindent is on
+ strdisplaywidth: 46 == calculated: 64
+ {
+
+ Test 12: breakindent + long indent
+ 56
+
+ ~
+ Test 13: breakindent with wrapping Tab
+ d
+ w
+
+ Test 14: breakindent + visual blockwise delete #1
+ e
+ ~
+ ~
+
+ Test 15: breakindent + visual blockwise delete #2
+ 1234567890
+ ~
+ ~ ]])
+ end)
+end)
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 045f5aa42f..97875c5147 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -25,7 +25,7 @@ describe('terminal window highlighting', function()
[5] = {background = 11},
[6] = {foreground = 130},
[7] = {reverse = true},
- [8] = {background = 11}
+ [8] = {background = 11},
})
screen:attach(false)
execute('enew | call termopen(["'..nvim_dir..'/tty-test"]) | startinsert')
@@ -121,7 +121,7 @@ describe('terminal window highlighting with custom palette', function()
clear()
screen = Screen.new(50, 7)
screen:set_default_attr_ids({
- [1] = {foreground = 1193046}
+ [1] = {foreground = 1193046, special = Screen.colors.Black}
})
screen:set_default_attr_ignore({
[1] = {bold = true},
@@ -130,7 +130,7 @@ describe('terminal window highlighting with custom palette', function()
[5] = {background = 11},
[6] = {foreground = 130},
[7] = {reverse = true},
- [8] = {background = 11}
+ [8] = {background = 11},
})
screen:attach(true)
nvim('set_var', 'terminal_color_3', '#123456')
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 06139277b2..0229b8bbf7 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local os = require('os')
-local clear, feed = helpers.clear, helpers.feed
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, request, eq = helpers.execute, helpers.request, helpers.eq
@@ -303,3 +303,311 @@ describe('Default highlight groups', function()
]], {[1] = {foreground = Screen.colors.Red, background = Screen.colors.Green}})
end)
end)
+
+describe('guisp (special/undercurl)', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(25,10)
+ screen:attach()
+ screen:set_default_attr_ignore({
+ [1] = {bold = true, foreground = Screen.colors.Blue},
+ [2] = {bold = true}
+ })
+ end)
+
+ it('can be set and is applied like foreground or background', function()
+ execute('syntax on')
+ execute('syn keyword TmpKeyword neovim')
+ execute('syn keyword TmpKeyword1 special')
+ execute('syn keyword TmpKeyword2 specialwithbg')
+ execute('syn keyword TmpKeyword3 specialwithfg')
+ execute('hi! Awesome guifg=red guibg=yellow guisp=red')
+ execute('hi! Awesome1 guisp=red')
+ execute('hi! Awesome2 guibg=yellow guisp=red')
+ execute('hi! Awesome3 guifg=red guisp=red')
+ execute('hi link TmpKeyword Awesome')
+ execute('hi link TmpKeyword1 Awesome1')
+ execute('hi link TmpKeyword2 Awesome2')
+ execute('hi link TmpKeyword3 Awesome3')
+ insert([[
+ neovim
+ awesome neovim
+ wordcontainingneovim
+ special
+ specialwithbg
+ specialwithfg
+ ]])
+ feed('Go<tab>neovim tabbed')
+ screen:expect([[
+ {1:neovim} |
+ awesome {1:neovim} |
+ wordcontainingneovim |
+ {2:special} |
+ {3:specialwithbg} |
+ {4:specialwithfg} |
+ |
+ {1:neovim} tabbed^ |
+ ~ |
+ -- INSERT -- |
+ ]],{
+ [1] = {background = Screen.colors.Yellow, foreground = Screen.colors.Red,
+ special = Screen.colors.Red},
+ [2] = {special = Screen.colors.Red},
+ [3] = {special = Screen.colors.Red, background = Screen.colors.Yellow},
+ [4] = {foreground = Screen.colors.Red, special = Screen.colors.Red},
+ })
+
+ end)
+end)
+
+describe("'cursorline' with 'listchars'", function()
+ local screen
+
+ local hlgroup_colors = {
+ NonText = Screen.colors.Blue,
+ Cursorline = Screen.colors.Grey90,
+ SpecialKey = Screen.colors.Red,
+ Visual = Screen.colors.LightGrey,
+ }
+
+ before_each(function()
+ clear()
+ screen = Screen.new(20,5)
+ screen:attach()
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("'cursorline' and 'cursorcolumn'", function()
+ screen:set_default_attr_ids({[1] = {background=hlgroup_colors.Cursorline}})
+ screen:set_default_attr_ignore( {{bold=true, foreground=hlgroup_colors.NonText}} )
+ execute('highlight clear ModeMsg')
+ execute('set cursorline')
+ feed('i')
+ screen:expect([[
+ {1:^ }|
+ ~ |
+ ~ |
+ ~ |
+ -- INSERT -- |
+ ]])
+ feed('abcdefg<cr>kkasdf')
+ screen:expect([[
+ abcdefg |
+ {1:kkasdf^ }|
+ ~ |
+ ~ |
+ -- INSERT -- |
+ ]])
+ feed('<esc>')
+ screen:expect([[
+ abcdefg |
+ {1:kkasd^f }|
+ ~ |
+ ~ |
+ |
+ ]])
+ execute('set nocursorline')
+ screen:expect([[
+ abcdefg |
+ kkasd^f |
+ ~ |
+ ~ |
+ :set nocursorline |
+ ]])
+ feed('k')
+ screen:expect([[
+ abcde^fg |
+ kkasdf |
+ ~ |
+ ~ |
+ :set nocursorline |
+ ]])
+ feed('jjji<cr><cr><cr><esc>')
+ screen:expect([[
+ kkasd |
+ |
+ |
+ ^f |
+ |
+ ]])
+ execute('set cursorline')
+ execute('set cursorcolumn')
+ feed('kkiabcdefghijk<esc>hh')
+ screen:expect([[
+ kkasd {1: } |
+ {1:abcdefgh^ijk }|
+ {1: } |
+ f {1: } |
+ |
+ ]])
+ feed('khh')
+ screen:expect([[
+ {1:kk^asd }|
+ ab{1:c}defghijk |
+ {1: } |
+ f {1: } |
+ |
+ ]])
+ end)
+
+ it("'cursorline' and with 'listchar' option: space, eol, tab, and trail", function()
+ screen:set_default_attr_ids({
+ [1] = {background=hlgroup_colors.Cursorline},
+ [2] = {
+ foreground=hlgroup_colors.SpecialKey,
+ background=hlgroup_colors.Cursorline,
+ },
+ [3] = {
+ background=hlgroup_colors.Cursorline,
+ foreground=hlgroup_colors.NonText,
+ bold=true,
+ },
+ [4] = {
+ foreground=hlgroup_colors.NonText,
+ bold=true,
+ },
+ [5] = {
+ foreground=hlgroup_colors.SpecialKey,
+ },
+ })
+ execute('highlight clear ModeMsg')
+ execute('highlight SpecialKey guifg=#FF0000')
+ execute('set cursorline')
+ execute('set tabstop=8')
+ execute('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list')
+ feed('i\t abcd <cr>\t abcd <cr><esc>k')
+ screen:expect([[
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {2:^>-------.}{1:abcd}{2:*}{3:¬}{1: }|
+ {4:¬} |
+ {4:~ }|
+ |
+ ]])
+ feed('k')
+ screen:expect([[
+ {2:^>-------.}{1:abcd}{2:*}{3:¬}{1: }|
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {4:¬} |
+ {4:~ }|
+ |
+ ]])
+ execute('set nocursorline')
+ screen:expect([[
+ {5:^>-------.}abcd{5:*}{4:¬} |
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {4:¬} |
+ {4:~ }|
+ :set nocursorline |
+ ]])
+ execute('set nowrap')
+ feed('ALorem ipsum dolor sit amet<ESC>0')
+ screen:expect([[
+ {5:^>-------.}abcd{5:.}Lorem{4:>}|
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {4:¬} |
+ {4:~ }|
+ |
+ ]])
+ execute('set cursorline')
+ screen:expect([[
+ {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{4:>}|
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {4:¬} |
+ {4:~ }|
+ :set cursorline |
+ ]])
+ feed('$')
+ screen:expect([[
+ {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
+ {4:<} |
+ {4:<} |
+ {4:~ }|
+ :set cursorline |
+ ]])
+ feed('G')
+ screen:expect([[
+ {5:>-------.}abcd{5:.}Lorem{4:>}|
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {3:^¬}{1: }|
+ {4:~ }|
+ :set cursorline |
+ ]])
+ end)
+
+ it("'listchar' in visual mode", function()
+ screen:set_default_attr_ids({
+ [1] = {background=hlgroup_colors.Cursorline},
+ [2] = {
+ foreground=hlgroup_colors.SpecialKey,
+ background=hlgroup_colors.Cursorline,
+ },
+ [3] = {
+ background=hlgroup_colors.Cursorline,
+ foreground=hlgroup_colors.NonText,
+ bold=true,
+ },
+ [4] = {
+ foreground=hlgroup_colors.NonText,
+ bold=true,
+ },
+ [5] = {
+ foreground=hlgroup_colors.SpecialKey,
+ },
+ [6] = {
+ background=hlgroup_colors.Visual,
+ },
+ [7] = {
+ background=hlgroup_colors.Visual,
+ foreground=hlgroup_colors.SpecialKey,
+ },
+ [8] = {
+ background=hlgroup_colors.Visual,
+ foreground=hlgroup_colors.NonText,
+ bold=true,
+ },
+ })
+ execute('highlight clear ModeMsg')
+ execute('highlight SpecialKey guifg=#FF0000')
+ execute('set cursorline')
+ execute('set tabstop=8')
+ execute('set nowrap')
+ execute('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list')
+ feed('i\t abcd <cr>\t abcd Lorem ipsum dolor sit amet<cr><esc>kkk0')
+ screen:expect([[
+ {2:^>-------.}{1:abcd}{2:*}{3:¬}{1: }|
+ {5:>-------.}abcd{5:.}Lorem{4:>}|
+ {4:¬} |
+ {4:~ }|
+ |
+ ]])
+ feed('lllvj')
+ screen:expect([[
+ {5:>-------.}a{6:bcd}{7:*}{8:¬} |
+ {7:>-------.}{6:a}^bcd{5:.}Lorem{4:>}|
+ {4:¬} |
+ {4:~ }|
+ -- VISUAL -- |
+ ]])
+ feed('<esc>V')
+ screen:expect([[
+ {5:>-------.}abcd{5:*}{4:¬} |
+ {7:>-------.}{6:a}^b{6:cd}{7:.}{6:Lorem}{4:>}|
+ {4:¬} |
+ {4:~ }|
+ -- VISUAL LINE -- |
+ ]])
+ feed('<esc>$')
+ screen:expect([[
+ {4:<} |
+ {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
+ {4:<} |
+ {4:~ }|
+ |
+ ]])
+ end)
+end)
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index d0d791308b..993bbd5b0e 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -23,7 +23,12 @@ describe('Mouse input', function()
screen:attach()
screen:set_default_attr_ids({
[1] = {background = hlgroup_colors.Visual},
- [2] = {bold = true}
+ [2] = {bold = true},
+ [3] = {
+ foreground = hlgroup_colors.NonText,
+ background = hlgroup_colors.Visual,
+ bold = true,
+ },
})
screen:set_default_attr_ignore( {{bold=true, foreground=hlgroup_colors.NonText}} )
feed('itesting<cr>mouse<cr>support and selection<esc>')
@@ -225,14 +230,14 @@ describe('Mouse input', function()
feed('<LeftDrag><2,2>')
screen:expect([[
testing |
- mo{1:use } |
+ mo{1:use}{3: } |
{1:su}^pport and selection |
~ |
{2:-- VISUAL --} |
]])
feed('<LeftDrag><0,0>')
screen:expect([[
- ^t{1:esting } |
+ ^t{1:esting}{3: } |
{1:mou}se |
support and selection |
~ |
@@ -293,7 +298,7 @@ describe('Mouse input', function()
screen:expect([[
testing |
mouse |
- {1:su}^p{1:port and selection } |
+ {1:su}^p{1:port and selection}{3: } |
~ |
{2:-- VISUAL LINE --} |
]])
@@ -321,8 +326,8 @@ describe('Mouse input', function()
]])
feed('<RightMouse><2,2>')
screen:expect([[
- {1:testing } |
- {1:mouse } |
+ {1:testing}{3: } |
+ {1:mouse}{3: } |
{1:su}^pport and selection |
~ |
{2:-- VISUAL --} |
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index a11fab18a2..6372cbe081 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -425,6 +425,10 @@ function Screen:_handle_update_bg(bg)
self._bg = bg
end
+function Screen:_handle_update_sp(sp)
+ self._sp = sp
+end
+
function Screen:_handle_suspend()
self.suspended = true
end
@@ -573,7 +577,7 @@ function Screen:_pprint_attrs(attrs)
local items = {}
for f, v in pairs(attrs) do
local desc = tostring(v)
- if f == "foreground" or f == "background" then
+ if f == "foreground" or f == "background" or f == "special" then
if Screen.colornames[v] ~= nil then
desc = "Screen.colors."..Screen.colornames[v]
end
@@ -614,7 +618,8 @@ function Screen:_equal_attrs(a, b)
a.underline == b.underline and a.undercurl == b.undercurl and
a.italic == b.italic and a.reverse == b.reverse and
a.foreground == b.foreground and
- a.background == b.background
+ a.background == b.background and
+ a.special == b.special
end
function Screen:_attr_index(attrs, attr)