diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 297939fbe1ab9977828d6c98f7d6b420dbe6a51a..9344e884e1ca5ffbcb76e54e148ca93e4bb51ce8 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.3b.  Last change: 2010 Jul 20
+*options.txt*	For Vim version 7.3b.  Last change: 2010 Jul 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1707,7 +1707,26 @@ A jump table for the options with a short description can be found at |Q_op|.
 		    combination with "menu" or "menuone".
 
 
-'conceallevel' 'conc'		*'conceallevel'* *'conc'*
+						*'concealcursor'* *'cocu'*
+'concealcursor' 'cocu'	string (default: "")
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+conceal|
+			feature}
+	Sets the modes in which text in the cursor line can also be concealed.
+	When the current mode is listed then concealing happens just like in
+	other lines.
+	  n		Normal mode
+	  v		Visual mode
+	  i		Insert mode
+
+	A useful value is "n".  This is used in help files.  So long as you
+	are moving around text is concealed, but when starting to insert text
+	or selecting a Visual area the concealed text is displayed, so that
+	you can see what you are doing.
+
+
+'conceallevel' 'cole'		*'conceallevel'* *'cole'*
 			number (default 0)
 			local to window
 			{not in Vi}
@@ -1727,7 +1746,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	3		Concealed text is completely hidden.
 
 	Note: in the cursor line concealed text is not hidden, so that you can
-	edit and copy the text.
+	edit and copy the text.  This can be changed with the 'concealcursor'
+	option.
 
 				*'confirm'* *'cf'* *'noconfirm'* *'nocf'*
 'confirm' 'cf'		boolean (default off)
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index 1272c4ca55b5b6f29c5b5155e20a26ea7ad39512..d02c944c261dad0ca105d834da0144b13892daa9 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -1,4 +1,4 @@
-*quickref.txt*  For Vim version 7.3b.  Last change: 2009 Jan 22
+*quickref.txt*  For Vim version 7.3b.  Last change: 2010 Jul 22
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -647,7 +647,8 @@ Short explanation of each option:		*option-list*
 'complete'	  'cpt'     specify how Insert mode completion works
 'completefunc'	  'cfu'     function to be used for Insert mode completion
 'completeopt'	  'cot'     options for Insert mode completion
-'conceallevel'	  'conc'    whether concealable text is shown or hidden 
+'concealcursor'	  'cocu'    whether concealable text is hidden in cursor line
+'conceallevel'	  'cole'    whether concealable text is shown or hidden 
 'confirm'	  'cf'	    ask what to do about unsaved/read-only files
 'conskey'	  'consk'   get keys directly from console (MS-DOS only)
 'copyindent'	  'ci'	    make 'autoindent' use existing indent structure
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 9c9caefc8592d1851d4ac130f971dabbbac2da3a..932377164d9fa9e2ebad804d7ef045fabe68cf7e 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1,4 +1,4 @@
-*syntax.txt*	For Vim version 7.3b.  Last change: 2010 Jul 21
+*syntax.txt*	For Vim version 7.3b.  Last change: 2010 Jul 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -3149,9 +3149,9 @@ conceal						*conceal* *:syn-conceal*
 
 When the "conceal" argument is given, the item is marked as concealable.
 Whether or not it is actually concealed depends on the value of the
-'conceallevel' option.  If 'modifiable' option is on, concealable items
-in the current line are always displayed unconcealed to be able to edit
-the line.
+'conceallevel' option.  The 'concealcursor' option is used to decide whether
+concealable items in the current line are displayed unconcealed to be able to
+edit the line.
 
 concealends						*:syn-concealends*
 
diff --git a/runtime/doc/tags b/runtime/doc/tags
index e36c6a4c4637d29ba1d40cf7bd854124d8c80bb7..45ee674c3274bf63465d94aac81163f4771eb9d7 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -127,6 +127,8 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'cmp'	options.txt	/*'cmp'*
 'cms'	options.txt	/*'cms'*
 'co'	options.txt	/*'co'*
+'cocu'	options.txt	/*'cocu'*
+'cole'	options.txt	/*'cole'*
 'colorcolumn'	options.txt	/*'colorcolumn'*
 'columns'	options.txt	/*'columns'*
 'com'	options.txt	/*'com'*
@@ -136,7 +138,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'complete'	options.txt	/*'complete'*
 'completefunc'	options.txt	/*'completefunc'*
 'completeopt'	options.txt	/*'completeopt'*
-'conc'	options.txt	/*'conc'*
+'concealcursor'	options.txt	/*'concealcursor'*
 'conceallevel'	options.txt	/*'conceallevel'*
 'confirm'	options.txt	/*'confirm'*
 'consk'	options.txt	/*'consk'*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index f7f7f12bc36c0a5ed8097ea8512790b44246a78b..3fd8132978df730066b28d7622d89ab3fcf75b48 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.3b.  Last change: 2010 Jul 22
+*todo.txt*      For Vim version 7.3b.  Last change: 2010 Jul 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,11 +30,16 @@ be worked on, but only if you sponsor Vim development.  See |sponsor|.
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-Conceal in help files doesn't work nice.  How about adding an 'concealcursor'
-option, when on:
-- cursorline is concealed.
-- line is redrawn on every movement
-- display function corrects cursor position.
+a |test| and a |test| and a |test|.
+Conceal in help files doesn't work nice.  How about adding a 'concealcursor'
+option:
+-> implemented, but column isn't quite right just after concealed character.
+- Don't conceal in Insert and Visual mode?  Or make 'concealcursor' a string
+  option with mode characters.
+- Check position in wrapped line.
+
+Trick with syntax ID works, but it's not nice.  Can we give a sequence nr to
+syntax item matches?  At least the ones with a replacement char.
 
 Include patch for horizontal scoll wheel? (Bjorn Winckler, 2010 Jul 20)
 Additional patch Jul 21.
@@ -272,6 +277,10 @@ Win32: use different args for SearchPath()? (Yasuhiro Matsumoto, 2009 Jan 30)
 Win32: completion of file name ":e c:\!test" results in ":e c:\\!test", which
 does not work. (Nieko Maatjes, 2009 Jan 8, Ingo Karkat, 2009 Jan 22)
 
+opening/closing window causes other window with 'winfixheight' to change
+height.  Also happens when there is another window in the frame, if it's not
+very high. (Yegappan Lakshmanan, 2010 Jul 22)
+
 Directory wrong in session file, caused by ":lcd" in BufEnter autocommand.
 (Felix Kater, 2009 Mar 3)
 
diff --git a/runtime/ftplugin/help.vim b/runtime/ftplugin/help.vim
index fe47f3944c3eb68ca707fc04b25290248ce1099c..fff952712796f61c9f145087175f08e716e5456d 100644
--- a/runtime/ftplugin/help.vim
+++ b/runtime/ftplugin/help.vim
@@ -11,9 +11,9 @@ let b:did_ftplugin = 1
 let s:cpo_save = &cpo
 set cpo&vim
 
-let b:undo_ftplugin = "setl fo< tw< conc<"
+let b:undo_ftplugin = "setl fo< tw< cole< cocu<"
 
-setlocal formatoptions+=tcroql textwidth=78 conc=2
+setlocal formatoptions+=tcroql textwidth=78 cole=2 cocu=n
 
 let &cpo = s:cpo_save
 unlet s:cpo_save
diff --git a/src/edit.c b/src/edit.c
index 87fd5696cfe96d61c5ffc3eb93d6396e30d0c887..3370a28f2dd572dc33ecba08daedda542004c4e5 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -377,6 +377,12 @@ edit(cmdchar, startln, count)
     }
 #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 @@ ins_redraw(ready)
 		    ||
 # 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 @@ ins_redraw(ready)
 		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 @@ ins_redraw(ready)
 	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)
-	{
-	    update_single_line(curwin, conceal_old_cursor_line);
-	    update_single_line(curwin, conceal_new_cursor_line);
+	if ((conceal_update_lines
+		&& (conceal_old_cursor_line != conceal_new_cursor_line
+		    || conceal_cursor_line(curwin)))
+		|| need_cursor_line_redraw)
+	{
+	    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 68ffe0ca5ff552670513542d84b8d5b42e639464..3f25898a0364953806db8186e8f4748f29e8f63e 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 bb5f3cfc6f8bc1f2ad3aed7722edccd0c907f118..93f1514290d24848490b758e0025bd728dbb8366 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1343,6 +1343,11 @@ EXTERN disptick_T	display_tick INIT(= 0);
 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 c8993232067ea33161f34c2ff57a486ec2536119..5aece03c2849b14f855e59baeec818773c5b4b56 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4922,7 +4922,7 @@ gui_update_screen()
 		||
 # 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 @@ gui_update_screen()
 	    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 @@ gui_update_screen()
     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 029b64c76eebdc193d43be598e0c535f863714ca..d94b32a38a84a8e7810f5cb82d1bf130056b207e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1098,7 +1098,7 @@ main_loop(cmdwin, noexmode)
 			||
 # 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 @@ main_loop(cmdwin, noexmode)
 							       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 @@ main_loop(cmdwin, noexmode)
 
 # 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 4d2f4c6547663ca79d423d08f6cf18af726b4c4e..d9e958840da4567cee2c19b0b2e9f45d184975d8 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -7623,6 +7623,11 @@ may_start_select(c)
 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 @@ n_start_visual_mode(c)
 #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 @@ n_opencmd(cap)
 		    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 f16c4ba44f2a58bb4256d45544ac75b9b259845c..8d7f09a54dccb60b045d391acb4388e852b562e0 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 @@ static struct vimoption
 			    {(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 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
 	    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 @@ set_bool_option(opt_idx, varp, value, opt_flags)
 	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 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
 	    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 @@ get_varp(p)
 	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 @@ copy_winopt(from, to)
 #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 @@ check_winopt(wop)
 #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 @@ clear_winopt(wop)
 #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 817e337ff63af395c8eb2a42b9a193692b83d445..216446748fe957da4a5553f1d7b5cfa0d2e8bd37 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 @@ enum
     , 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 05114d0e6ed4a8fa33281d1daf7ef7dd04e40a89..efaf4c6d0e91aa3a178ec15cf9c420faf3943b01 100644
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -8,6 +8,8 @@ void redraw_buf_later __ARGS((buf_T *buf, int type));
 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 71eb16fca595b50d0eaeebf6d0a758fd5a41657a..f9183e126537cff56d0b74f04dc06231b220f167 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -587,6 +587,44 @@ update_screen(type)
 }
 
 #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 @@ update_single_line(wp, lnum)
 	}
 # endif
     }
+    need_cursor_line_redraw = FALSE;
 }
 #endif
 
@@ -2781,7 +2820,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
     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 @@ win_line(wp, lnum, startrow, endrow, nochange)
 	    }
 
 #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 @@ win_line(wp, lnum, startrow, endrow, nochange)
 #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 @@ win_line(wp, lnum, startrow, endrow, nochange)
 	    }
 	}
 #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 42b1d2abc3a06d3d92812856bbe5c4269e13f14c..7b8acee7906263a1534ed4f0d123ab16375a0eff 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -216,8 +216,10 @@ typedef struct
     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 cabee59aad04082996d38b04c4e4278702d93379..1337807b6485339bb33b7f03ed28840265095397 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1912,6 +1912,10 @@ ui_cursor_shape()
 # 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 77f57bcaf628bc03fa6ee119011b78ed60fb1fae..58b55babbee371dc597be0ed32f6ef6d609f657d 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -2711,7 +2711,7 @@ u_undo_end(did_undo, absolute)
 
 	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);
 	}
     }