Add the 'concealcursor' option to decide when the cursor line is to be
concealed or not.
Rename 'conc' to 'cole' as the short name for 'conceallevel'.
diff --git a/src/edit.c b/src/edit.c
index 87fd569..3370a28 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -377,6 +377,12 @@
}
#endif
+#ifdef FEAT_CONCEAL
+ /* Check if the cursor line needs redrawing before changing State. If
+ * 'concealcursor' is "n" it needs to be redrawn without concealing. */
+ conceal_check_cursur_line_redraw();
+#endif
+
#ifdef FEAT_MOUSE
/*
* When doing a paste with the middle mouse button, Insstart is set to
@@ -1476,7 +1482,7 @@
||
# endif
# ifdef FEAT_CONCEAL
- curwin->w_p_conc > 0
+ curwin->w_p_cole > 0
# endif
)
&& !equalpos(last_cursormoved, curwin->w_cursor)
@@ -1498,7 +1504,7 @@
apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf);
# endif
# ifdef FEAT_CONCEAL
- if (curwin->w_p_conc > 0)
+ if (curwin->w_p_cole > 0)
{
conceal_old_cursor_line = last_cursormoved.lnum;
conceal_new_cursor_line = curwin->w_cursor.lnum;
@@ -1513,11 +1519,15 @@
else if (clear_cmdline || redraw_cmdline)
showmode(); /* clear cmdline and show mode */
# if defined(FEAT_CONCEAL)
- if (conceal_update_lines
- && conceal_old_cursor_line != conceal_new_cursor_line)
+ if ((conceal_update_lines
+ && (conceal_old_cursor_line != conceal_new_cursor_line
+ || conceal_cursor_line(curwin)))
+ || need_cursor_line_redraw)
{
- update_single_line(curwin, conceal_old_cursor_line);
- update_single_line(curwin, conceal_new_cursor_line);
+ if (conceal_old_cursor_line != conceal_new_cursor_line)
+ update_single_line(curwin, conceal_old_cursor_line);
+ update_single_line(curwin, conceal_new_cursor_line == 0
+ ? curwin->w_cursor.lnum : conceal_new_cursor_line);
curwin->w_valid &= ~VALID_CROW;
}
# endif
diff --git a/src/feature.h b/src/feature.h
index 68ffe0c..3f25898 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -1163,8 +1163,11 @@
#endif
/* GUI and some consoles can change the shape of the cursor. The code is also
- * needed for the 'mouseshape' option. */
-#if defined(FEAT_GUI) || defined(MCH_CURSOR_SHAPE) || defined(FEAT_MOUSESHAPE) \
+ * needed for the 'mouseshape' and 'concealcursor' options. */
+#if defined(FEAT_GUI) \
+ || defined(MCH_CURSOR_SHAPE) \
+ || defined(FEAT_MOUSESHAPE) \
+ || defined(FEAT_CONCEAL) \
|| (defined(UNIX) && defined(FEAT_NORMAL))
# define CURSOR_SHAPE
#endif
diff --git a/src/globals.h b/src/globals.h
index bb5f3cf..93f1514 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1343,6 +1343,11 @@
EXTERN linenr_T spell_redraw_lnum INIT(= 0);
#endif
+#ifdef FEAT_CONCEAL
+/* Set when the cursor line needs to be redrawn. */
+EXTERN int need_cursor_line_redraw INIT(= FALSE);
+#endif
+
#ifdef ALT_X_INPUT
/* we need to be able to go into the dispatch loop while processing a command
* received via alternate input. However, we don't want to process another
diff --git a/src/gui.c b/src/gui.c
index c899323..5aece03 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4922,7 +4922,7 @@
||
# endif
# ifdef FEAT_CONCEAL
- curwin->w_p_conc > 0
+ curwin->w_p_cole > 0
# endif
)
&& !equalpos(last_cursormoved, curwin->w_cursor))
@@ -4932,7 +4932,7 @@
apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, FALSE, curbuf);
# endif
# ifdef FEAT_CONCEAL
- if (curwin->w_p_conc > 0)
+ if (curwin->w_p_cole > 0)
{
conceal_old_cursor_line = last_cursormoved.lnum;
conceal_new_cursor_line = curwin->w_cursor.lnum;
@@ -4947,9 +4947,12 @@
setcursor();
# if defined(FEAT_CONCEAL)
if (conceal_update_lines
- && conceal_old_cursor_line != conceal_new_cursor_line)
+ && (conceal_old_cursor_line != conceal_new_cursor_line
+ || conceal_cursor_line(curwin)
+ || need_cursor_line_redraw))
{
- update_single_line(curwin, conceal_old_cursor_line);
+ if (conceal_old_cursor_line != conceal_new_cursor_line)
+ update_single_line(curwin, conceal_old_cursor_line);
update_single_line(curwin, conceal_new_cursor_line);
curwin->w_valid &= ~VALID_CROW;
}
diff --git a/src/main.c b/src/main.c
index 029b64c..d94b32a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1098,7 +1098,7 @@
||
# endif
# ifdef FEAT_CONCEAL
- curwin->w_p_conc > 0
+ curwin->w_p_cole > 0
# endif
)
&& !equalpos(last_cursormoved, curwin->w_cursor))
@@ -1109,7 +1109,7 @@
FALSE, curbuf);
# endif
# ifdef FEAT_CONCEAL
- if (curwin->w_p_conc > 0)
+ if (curwin->w_p_cole > 0)
{
conceal_old_cursor_line = last_cursormoved.lnum;
conceal_new_cursor_line = curwin->w_cursor.lnum;
@@ -1197,9 +1197,12 @@
# if defined(FEAT_CONCEAL)
if (conceal_update_lines
- && conceal_old_cursor_line != conceal_new_cursor_line)
+ && (conceal_old_cursor_line != conceal_new_cursor_line
+ || conceal_cursor_line(curwin)
+ || need_cursor_line_redraw))
{
- update_single_line(curwin, conceal_old_cursor_line);
+ if (conceal_old_cursor_line != conceal_new_cursor_line)
+ update_single_line(curwin, conceal_old_cursor_line);
update_single_line(curwin, conceal_new_cursor_line);
curwin->w_valid &= ~VALID_CROW;
}
diff --git a/src/normal.c b/src/normal.c
index 4d2f4c6..d9e9588 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -7623,6 +7623,11 @@
n_start_visual_mode(c)
int c;
{
+#ifdef FEAT_CONCEAL
+ /* Check for redraw before changing the state. */
+ conceal_check_cursur_line_redraw();
+#endif
+
VIsual_mode = c;
VIsual_active = TRUE;
VIsual_reselect = TRUE;
@@ -7642,6 +7647,11 @@
#ifdef FEAT_MOUSE
setmouse();
#endif
+#ifdef FEAT_CONCEAL
+ /* Check for redraw after changing the state. */
+ conceal_check_cursur_line_redraw();
+#endif
+
if (p_smd && msg_silent == 0)
redraw_cmdline = TRUE; /* show visual mode later */
#ifdef FEAT_CLIPBOARD
@@ -8296,7 +8306,7 @@
0, 0))
{
#ifdef FEAT_CONCEAL
- if (curwin->w_p_conc > 0 && oldline != curwin->w_cursor.lnum)
+ if (curwin->w_p_cole > 0 && oldline != curwin->w_cursor.lnum)
update_single_line(curwin, oldline);
#endif
/* When '#' is in 'cpoptions' ignore the count. */
diff --git a/src/option.c b/src/option.c
index f16c4ba..8d7f09a 100644
--- a/src/option.c
+++ b/src/option.c
@@ -248,7 +248,8 @@
# define PV_CRBIND OPT_WIN(WV_CRBIND)
#endif
#ifdef FEAT_CONCEAL
-# define PV_CONCEAL OPT_WIN(WV_CONCEAL)
+# define PV_COCU OPT_WIN(WV_COCU)
+# define PV_COLE OPT_WIN(WV_COLE)
#endif
/* WV_ and BV_ values get typecasted to this for the "indir" field */
@@ -816,9 +817,18 @@
{(char_u *)0L, (char_u *)0L}
#endif
SCRIPTID_INIT},
- {"conceallevel","conc", P_NUM|P_RWIN|P_VI_DEF,
+ {"concealcursor","cocu", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF,
#ifdef FEAT_CONCEAL
- (char_u *)VAR_WIN, PV_CONCEAL,
+ (char_u *)VAR_WIN, PV_COCU,
+ {(char_u *)"", (char_u *)NULL}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"conceallevel","cole", P_NUM|P_RWIN|P_VI_DEF,
+#ifdef FEAT_CONCEAL
+ (char_u *)VAR_WIN, PV_COLE,
#else
(char_u *)NULL, PV_NONE,
#endif
@@ -6848,6 +6858,10 @@
p = (char_u *)CPO_ALL;
else if (varp == &(curbuf->b_p_fo))
p = (char_u *)FO_ALL;
+#ifdef FEAT_CONCEAL
+ else if (varp == &curwin->w_p_cocu)
+ p = (char_u *)COCU_ALL;
+#endif
else if (varp == &p_mouse)
{
#ifdef FEAT_MOUSE
@@ -7505,7 +7519,7 @@
redraw_titles();
# endif
# ifdef FEAT_CONCEAL
- if (curwin->w_p_conc > 0)
+ if (curwin->w_p_cole > 0)
update_single_line(curwin, curwin->w_cursor.lnum);
# endif
}
@@ -8273,17 +8287,17 @@
ml_open_files();
}
#ifdef FEAT_CONCEAL
- else if (pp == &curwin->w_p_conc)
+ else if (pp == &curwin->w_p_cole)
{
- if (curwin->w_p_conc < 0)
+ if (curwin->w_p_cole < 0)
{
errmsg = e_positive;
- curwin->w_p_conc = 0;
+ curwin->w_p_cole = 0;
}
- else if (curwin->w_p_conc > 3)
+ else if (curwin->w_p_cole > 3)
{
errmsg = e_invarg;
- curwin->w_p_conc = 3;
+ curwin->w_p_cole = 3;
}
}
#endif
@@ -9554,7 +9568,8 @@
case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
#endif
#ifdef FEAT_CONCEAL
- case PV_CONCEAL: return (char_u *)&(curwin->w_p_conc);
+ case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
+ case PV_COLE: return (char_u *)&(curwin->w_p_cole);
#endif
case PV_AI: return (char_u *)&(curbuf->b_p_ai);
@@ -9749,6 +9764,9 @@
#ifdef FEAT_DIFF
to->wo_diff = from->wo_diff;
#endif
+#ifdef FEAT_CONCEAL
+ to->wo_cocu = vim_strsave(from->wo_cocu);
+#endif
#ifdef FEAT_FOLDING
to->wo_fdc = from->wo_fdc;
to->wo_fen = from->wo_fen;
@@ -9802,6 +9820,9 @@
#ifdef FEAT_SYN_HL
check_string_option(&wop->wo_cc);
#endif
+#ifdef FEAT_CONCEAL
+ check_string_option(&wop->wo_cocu);
+#endif
}
/*
@@ -9829,6 +9850,9 @@
#ifdef FEAT_SYN_HL
clear_string_option(&wop->wo_cc);
#endif
+#ifdef FEAT_CONCEAL
+ clear_string_option(&wop->wo_cocu);
+#endif
}
/*
diff --git a/src/option.h b/src/option.h
index 817e337..2164467 100644
--- a/src/option.h
+++ b/src/option.h
@@ -189,6 +189,8 @@
#define MOUSE_NONE ' ' /* don't use Visual selection */
#define MOUSE_NONEF 'x' /* forced modeless selection */
+#define COCU_ALL "nvi" /* flags for 'concealcursor' */
+
/* characters for p_shm option: */
#define SHM_RO 'r' /* readonly */
#define SHM_MOD 'm' /* modified */
@@ -1029,7 +1031,8 @@
, WV_ARAB
#endif
#ifdef FEAT_CONCEAL
- , WV_CONCEAL
+ , WV_COCU
+ , WV_COLE
#endif
#ifdef FEAT_CURSORBIND
, WV_CRBIND
diff --git a/src/proto/screen.pro b/src/proto/screen.pro
index 05114d0..efaf4c6 100644
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -8,6 +8,8 @@
void redrawWinline __ARGS((linenr_T lnum, int invalid));
void update_curbuf __ARGS((int type));
void update_screen __ARGS((int type));
+int conceal_cursor_line __ARGS((win_T *wp));
+void conceal_check_cursur_line_redraw __ARGS((void));
void update_single_line __ARGS((win_T *wp, linenr_T lnum));
void update_debug_sign __ARGS((buf_T *buf, linenr_T lnum));
void updateWindow __ARGS((win_T *wp));
diff --git a/src/screen.c b/src/screen.c
index 71eb16f..f9183e1 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -587,6 +587,44 @@
}
#if defined(FEAT_CONCEAL) || defined(PROTO)
+/*
+ * Return TRUE if the cursor line in window "wp" may be concealed, according
+ * to the 'concealcursor' option.
+ */
+ int
+conceal_cursor_line(wp)
+ win_T *wp;
+{
+ int c;
+
+ if (*wp->w_p_cocu == NUL)
+ return FALSE;
+ if (get_real_state() & VISUAL)
+ c = 'v';
+ else if (State & INSERT)
+ c = 'i';
+ else if (State & NORMAL)
+ c = 'n';
+ else
+ return FALSE;
+ return vim_strchr(wp->w_p_cocu, c) != NULL;
+}
+
+/*
+ * Check if the cursor line needs to be redrawn because of 'concealcursor'.
+ */
+ void
+conceal_check_cursur_line_redraw()
+{
+ if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin))
+ {
+ need_cursor_line_redraw = TRUE;
+ /* Need to recompute cursor column, e.g., when starting Visual mode
+ * without concealing. */
+ curs_columns(TRUE);
+ }
+}
+
void
update_single_line(wp, lnum)
win_T *wp;
@@ -632,6 +670,7 @@
}
# endif
}
+ need_cursor_line_redraw = FALSE;
}
#endif
@@ -2781,7 +2820,8 @@
int is_concealing = FALSE;
int boguscols = 0; /* nonexistent columns added to force
wrapping */
- int vcol_off = 0; /* offset for concealed characters */
+ int vcol_off = 0; /* offset for concealed characters */
+ int did_wcol = FALSE;
# define VCOL_HLC (vcol - vcol_off)
#else
# define VCOL_HLC (vcol)
@@ -4381,14 +4421,15 @@
}
#ifdef FEAT_CONCEAL
- if ( wp->w_p_conc > 0
- && (lnum != wp->w_cursor.lnum || curwin != wp)
+ if ( wp->w_p_cole > 0
+ && (wp != curwin || lnum != wp->w_cursor.lnum ||
+ conceal_cursor_line(wp))
&& (syntax_flags & HL_CONCEAL) != 0)
{
char_attr = conceal_attr;
if (prev_syntax_id != syntax_id
- && (syn_get_sub_char() != NUL || wp->w_p_conc == 1)
- && wp->w_p_conc != 3)
+ && (syn_get_sub_char() != NUL || wp->w_p_cole == 1)
+ && wp->w_p_cole != 3)
{
/* First time at this concealed item: display one
* character. */
@@ -4447,6 +4488,18 @@
#endif /* FEAT_CONCEAL */
}
+#ifdef FEAT_CONCEAL
+ /* In the cursor line and we may be concealing characters: correct
+ * the cursor column when we reach its position. */
+ if (!did_wcol && wp == curwin && lnum == wp->w_cursor.lnum
+ && conceal_cursor_line(wp)
+ && (int)wp->w_virtcol <= vcol + n_skip)
+ {
+ wp->w_wcol = col - boguscols;
+ did_wcol = TRUE;
+ }
+#endif
+
/* Don't override visual selection highlighting. */
if (n_attr > 0
&& draw_state == WL_LINE
@@ -4913,7 +4966,7 @@
}
}
#ifdef FEAT_CONCEAL
- else if (wp->w_p_conc > 0 && is_concealing)
+ else if (wp->w_p_cole > 0 && is_concealing)
{
--n_skip;
++vcol_off;
diff --git a/src/structs.h b/src/structs.h
index 42b1d2a..7b8acee 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -216,8 +216,10 @@
int wo_wrap;
#define w_p_wrap w_onebuf_opt.wo_wrap /* 'wrap' */
#ifdef FEAT_CONCEAL
- long wo_conc; /* 'conceal' */
-# define w_p_conc w_onebuf_opt.wo_conc
+ char_u *wo_cocu; /* 'concealcursor' */
+# define w_p_cocu w_onebuf_opt.wo_cocu
+ long wo_cole; /* 'conceallevel' */
+# define w_p_cole w_onebuf_opt.wo_cole
#endif
#ifdef FEAT_CURSORBIND
int wo_crb;
diff --git a/src/ui.c b/src/ui.c
index cabee59..1337807 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1912,6 +1912,10 @@
# ifdef MCH_CURSOR_SHAPE
mch_update_cursor();
# endif
+
+# ifdef FEAT_CONCEAL
+ conceal_check_cursur_line_redraw();
+# endif
}
#endif
diff --git a/src/undo.c b/src/undo.c
index 77f57bc..58b55ba 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -2711,7 +2711,7 @@
FOR_ALL_WINDOWS(wp)
{
- if (wp->w_buffer == curbuf && wp->w_p_conc > 0)
+ if (wp->w_buffer == curbuf && wp->w_p_cole > 0)
redraw_win_later(wp, NOT_VALID);
}
}