changeset 28773:d770568e6c98 v8.2.4911

patch 8.2.4911: the mode #defines are not clearly named Commit: https://github.com/vim/vim/commit/249591057b4840785c50e41dd850efb8a8faf435 Author: Bram Moolenaar <Bram@vim.org> Date: Sat May 7 20:01:16 2022 +0100 patch 8.2.4911: the mode #defines are not clearly named Problem: The mode #defines are not clearly named. Solution: Prepend MODE_. Renumber them to put the mapped modes first.
author Bram Moolenaar <Bram@vim.org>
date Sat, 07 May 2022 21:15:06 +0200
parents 7b07ca0bb292
children 238e79812a48
files src/autocmd.c src/buffer.c src/change.c src/charset.c src/cindent.c src/clipboard.c src/debugger.c src/digraph.c src/drawline.c src/drawscreen.c src/edit.c src/evalfunc.c src/ex_cmds.c src/ex_docmd.c src/ex_getln.c src/fileio.c src/fold.c src/getchar.c src/globals.h src/gui.c src/gui_gtk.c src/gui_w32.c src/gui_xim.c src/indent.c src/insexpand.c src/macros.h src/main.c src/map.c src/menu.c src/message.c src/misc1.c src/misc2.c src/mouse.c src/netbeans.c src/normal.c src/ops.c src/option.c src/os_unix.c src/os_win32.c src/popupmenu.c src/screen.c src/search.c src/tag.c src/term.c src/terminal.c src/textformat.c src/version.c src/vim.h src/window.c
diffstat 49 files changed, 514 insertions(+), 490 deletions(-) [+]
line wrap: on
line diff
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -1758,7 +1758,7 @@ apply_autocmds_retval(
     static int
 has_cursorhold(void)
 {
-    return (first_autopat[(int)(get_real_state() == NORMAL_BUSY
+    return (first_autopat[(int)(get_real_state() == MODE_NORMAL_BUSY
 			    ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL);
 }
 
@@ -1777,7 +1777,7 @@ trigger_cursorhold(void)
 	    && !ins_compl_active())
     {
 	state = get_real_state();
-	if (state == NORMAL_BUSY || (state & INSERT) != 0)
+	if (state == MODE_NORMAL_BUSY || (state & MODE_INSERT) != 0)
 	    return TRUE;
     }
     return FALSE;
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1774,7 +1774,7 @@ set_curbuf(buf_T *buf, int action)
 	    // another window, might be a timer doing something in another
 	    // window.
 	    if (prevbuf == curbuf
-			 && ((State & INSERT) == 0 || curbuf->b_nwindows <= 1))
+		    && ((State & MODE_INSERT) == 0 || curbuf->b_nwindows <= 1))
 		u_sync(FALSE);
 	    close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
 		    unload ? action : (action == DOBUF_GOTO
@@ -4700,8 +4700,8 @@ build_stl_str_hl(
 	    break;
 
 	case STL_COLUMN:
-	    num = !(State & INSERT) && empty_line
-		  ? 0 : (int)wp->w_cursor.col + 1;
+	    num = (State & MODE_INSERT) == 0 && empty_line
+					       ? 0 : (int)wp->w_cursor.col + 1;
 	    break;
 
 	case STL_VIRTCOL:
@@ -4709,8 +4709,8 @@ build_stl_str_hl(
 	    virtcol = wp->w_virtcol + 1;
 	    // Don't display %V if it's the same as %c.
 	    if (opt == STL_VIRTCOL_ALT
-		    && (virtcol == (colnr_T)(!(State & INSERT) && empty_line
-			    ? 0 : (int)wp->w_cursor.col + 1)))
+		    && (virtcol == (colnr_T)((State & MODE_INSERT) == 0
+			       && empty_line ? 0 : (int)wp->w_cursor.col + 1)))
 		break;
 	    num = (long)virtcol;
 	    break;
@@ -4755,9 +4755,9 @@ build_stl_str_hl(
 	case STL_OFFSET:
 #ifdef FEAT_BYTEOFF
 	    l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
-	    num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ?
-		  0L : l + 1 + (!(State & INSERT) && empty_line ?
-				0 : (int)wp->w_cursor.col);
+	    num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0
+		       ? 0L : l + 1 + ((State & MODE_INSERT) == 0 && empty_line
+				? 0 : (int)wp->w_cursor.col);
 #endif
 	    break;
 
--- a/src/change.c
+++ b/src/change.c
@@ -988,7 +988,7 @@ ins_bytes_len(char_u *p, int len)
 
 /*
  * Insert or replace a single character at the cursor position.
- * When in REPLACE or VREPLACE mode, replace any existing character.
+ * When in MODE_REPLACE or MODE_VREPLACE state, replace any existing character.
  * Caller must have prepared for undo.
  * For multi-byte characters we get the whole character, the caller must
  * convert bytes to a character.
@@ -1119,7 +1119,7 @@ ins_char_bytes(char_u *buf, int charlen)
 
     // If we're in Insert or Replace mode and 'showmatch' is set, then briefly
     // show the match for right parens and braces.
-    if (p_sm && (State & INSERT)
+    if (p_sm && (State & MODE_INSERT)
 	    && msg_silent == 0
 	    && !ins_compl_active())
     {
@@ -1342,10 +1342,10 @@ del_bytes(
 /*
  * open_line: Add a new line below or above the current line.
  *
- * For VREPLACE mode, we only add a new line when we get to the end of the
- * file, otherwise we just start replacing the next line.
+ * For MODE_VREPLACE state, we only add a new line when we get to the end of
+ * the file, otherwise we just start replacing the next line.
  *
- * Caller must take care of undo.  Since VREPLACE may affect any number of
+ * Caller must take care of undo.  Since MODE_VREPLACE may affect any number of
  * lines however, it may call u_save_cursor() again when starting to change a
  * new line.
  * "flags": OPENLINE_DELSPACES	delete spaces after cursor
@@ -1416,7 +1416,7 @@ open_line(
 
     if (State & VREPLACE_FLAG)
     {
-	// With VREPLACE we make a copy of the next line, which we will be
+	// With MODE_VREPLACE we make a copy of the next line, which we will be
 	// starting to replace.  First make the new line empty and let vim play
 	// with the indenting and comment leader to its heart's content.  Then
 	// we grab what it ended up putting on the new line, put back the
@@ -1430,11 +1430,11 @@ open_line(
 	if (next_line == NULL)	    // out of memory!
 	    goto theend;
 
-	// In VREPLACE mode, a NL replaces the rest of the line, and starts
-	// replacing the next line, so push all of the characters left on the
-	// line onto the replace stack.  We'll push any other characters that
-	// might be replaced at the start of the next line (due to autoindent
-	// etc) a bit later.
+	// In MODE_VREPLACE state, a NL replaces the rest of the line, and
+	// starts replacing the next line, so push all of the characters left
+	// on the line onto the replace stack.  We'll push any other characters
+	// that might be replaced at the start of the next line (due to
+	// autoindent etc) a bit later.
 	replace_push(NUL);  // Call twice because BS over NL expects it
 	replace_push(NUL);
 	p = saved_line + curwin->w_cursor.col;
@@ -1448,7 +1448,7 @@ open_line(
 	saved_line[curwin->w_cursor.col] = NUL;
     }
 
-    if ((State & INSERT) && !(State & VREPLACE_FLAG))
+    if ((State & MODE_INSERT) && (State & VREPLACE_FLAG) == 0)
     {
 	p_extra = saved_line + curwin->w_cursor.col;
 #ifdef FEAT_SMARTINDENT
@@ -2077,7 +2077,7 @@ open_line(
 	}
     }
 
-    // (State == INSERT || State == REPLACE), only when dir == FORWARD
+    // (State == MODE_INSERT || State == MODE_REPLACE), only when dir == FORWARD
     if (p_extra != NULL)
     {
 	*p_extra = saved_char;		// restore char that NUL replaced
@@ -2085,8 +2085,9 @@ open_line(
 	// When 'ai' set or "flags" has OPENLINE_DELSPACES, skip to the first
 	// non-blank.
 	//
-	// When in REPLACE mode, put the deleted blanks on the replace stack,
-	// preceded by a NUL, so they can be put back when a BS is entered.
+	// When in MODE_REPLACE state, put the deleted blanks on the replace
+	// stack, preceded by a NUL, so they can be put back when a BS is
+	// entered.
 	if (REPLACE_NORMAL(State))
 	    replace_push(NUL);	    // end of extra blanks
 	if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES))
@@ -2156,7 +2157,7 @@ open_line(
 	    mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
 	did_append = TRUE;
 #ifdef FEAT_PROP_POPUP
-	if ((State & INSERT) && !(State & VREPLACE_FLAG))
+	if ((State & MODE_INSERT) && (State & VREPLACE_FLAG) == 0)
 	    // properties after the split move to the next line
 	    adjust_props_for_split(curwin->w_cursor.lnum, curwin->w_cursor.lnum,
 						  curwin->w_cursor.col + 1, 0);
@@ -2164,7 +2165,7 @@ open_line(
     }
     else
     {
-	// In VREPLACE mode we are starting to replace the next line.
+	// In MODE_VREPLACE state we are starting to replace the next line.
 	curwin->w_cursor.lnum++;
 	if (curwin->w_cursor.lnum >= Insstart.lnum + vr_lines_changed)
 	{
@@ -2212,8 +2213,8 @@ open_line(
 
 	ai_col = curwin->w_cursor.col;
 
-	// In REPLACE mode, for each character in the new indent, there must
-	// be a NUL on the replace stack, for when it is deleted with BS
+	// In MODE_REPLACE state, for each character in the new indent, there
+	// must be a NUL on the replace stack, for when it is deleted with BS
 	if (REPLACE_NORMAL(State))
 	    for (n = 0; n < (int)curwin->w_cursor.col; ++n)
 		replace_push(NUL);
@@ -2224,8 +2225,8 @@ open_line(
 #endif
     }
 
-    // In REPLACE mode, for each character in the extra leader, there must be
-    // a NUL on the replace stack, for when it is deleted with BS.
+    // In MODE_REPLACE state, for each character in the extra leader, there
+    // must be a NUL on the replace stack, for when it is deleted with BS.
     if (REPLACE_NORMAL(State))
 	while (lead_len-- > 0)
 	    replace_push(NUL);
@@ -2234,7 +2235,7 @@ open_line(
 
     if (dir == FORWARD)
     {
-	if (trunc_line || (State & INSERT))
+	if (trunc_line || (State & MODE_INSERT))
 	{
 	    // truncate current line at cursor
 	    saved_line[curwin->w_cursor.col] = NUL;
@@ -2270,13 +2271,13 @@ open_line(
     curwin->w_cursor.coladd = 0;
 
 #if defined(FEAT_LISP) || defined(FEAT_CINDENT)
-    // In VREPLACE mode, we are handling the replace stack ourselves, so stop
-    // fixthisline() from doing it (via change_indent()) by telling it we're in
-    // normal INSERT mode.
+    // In MODE_VREPLACE state, we are handling the replace stack ourselves, so
+    // stop fixthisline() from doing it (via change_indent()) by telling it
+    // we're in normal MODE_INSERT state.
     if (State & VREPLACE_FLAG)
     {
 	vreplace_mode = State;	// So we know to put things right later
-	State = INSERT;
+	State = MODE_INSERT;
     }
     else
 	vreplace_mode = 0;
@@ -2305,9 +2306,9 @@ open_line(
 	State = vreplace_mode;
 #endif
 
-    // Finally, VREPLACE gets the stuff on the new line, then puts back the
-    // original line, and inserts the new stuff char by char, pushing old stuff
-    // onto the replace stack (via ins_char()).
+    // Finally, MODE_VREPLACE gets the stuff on the new line, then puts back
+    // the original line, and inserts the new stuff char by char, pushing old
+    // stuff onto the replace stack (via ins_char()).
     if (State & VREPLACE_FLAG)
     {
 	// Put new line in p_extra
--- a/src/charset.c
+++ b/src/charset.c
@@ -1300,7 +1300,7 @@ getvcol(
     if (cursor != NULL)
     {
 	if (*ptr == TAB
-		&& (State & NORMAL)
+		&& (State & MODE_NORMAL)
 		&& !wp->w_p_list
 		&& !virtual_active()
 		&& !(VIsual_active
--- a/src/cindent.c
+++ b/src/cindent.c
@@ -2114,7 +2114,7 @@ get_c_indent(void)
     // inserting new stuff.
     // For unknown reasons the cursor might be past the end of the line, thus
     // check for that.
-    if ((State & INSERT)
+    if ((State & MODE_INSERT)
 	    && curwin->w_cursor.col < (colnr_T)STRLEN(linecopy)
 	    && linecopy[curwin->w_cursor.col] == ')')
 	linecopy[curwin->w_cursor.col] = NUL;
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -77,7 +77,7 @@ clip_update_selection(Clipboard_T *clip)
     pos_T	    start, end;
 
     // If visual mode is only due to a redo command ("."), then ignore it
-    if (!redo_VIsual_busy && VIsual_active && (State & NORMAL))
+    if (!redo_VIsual_busy && VIsual_active && (State & MODE_NORMAL))
     {
 	if (LT_POS(VIsual, curwin->w_cursor))
 	{
@@ -142,8 +142,8 @@ clip_own_selection(Clipboard_T *cbd)
 	    // selected area.  There is no specific redraw command for this,
 	    // just redraw all windows on the current buffer.
 	    if (cbd->owned
-		    && (get_real_state() == VISUAL
-					    || get_real_state() == SELECTMODE)
+		    && (get_real_state() == MODE_VISUAL
+					    || get_real_state() == MODE_SELECT)
 		    && (cbd == &clip_star ? clip_isautosel_star()
 						      : clip_isautosel_plus())
 		    && HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC))
@@ -195,8 +195,8 @@ clip_lose_selection(Clipboard_T *cbd)
 	// area.  There is no specific redraw command for this, just redraw all
 	// windows on the current buffer.
 	if (was_owned
-		&& (get_real_state() == VISUAL
-					    || get_real_state() == SELECTMODE)
+		&& (get_real_state() == MODE_VISUAL
+					    || get_real_state() == MODE_SELECT)
 		&& (cbd == &clip_star ?
 				clip_isautosel_star() : clip_isautosel_plus())
 		&& HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC)
@@ -214,7 +214,7 @@ clip_lose_selection(Clipboard_T *cbd)
     static void
 clip_copy_selection(Clipboard_T *clip)
 {
-    if (VIsual_active && (State & NORMAL) && clip->available)
+    if (VIsual_active && (State & MODE_NORMAL) && clip->available)
     {
 	clip_update_selection(clip);
 	clip_free_selection(clip);
--- a/src/debugger.c
+++ b/src/debugger.c
@@ -88,7 +88,7 @@ do_debug(char_u *cmd)
     emsg_silent = FALSE;	// display error messages
     redir_off = TRUE;		// don't redirect debug commands
 
-    State = NORMAL;
+    State = MODE_NORMAL;
     debug_mode = TRUE;
 
     if (!debug_did_msg)
--- a/src/digraph.c
+++ b/src/digraph.c
@@ -2566,7 +2566,7 @@ ex_loadkeymap(exarg_T *eap)
 	vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s",
 				((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from,
 				 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to);
-	(void)do_map(2, buf, LANGMAP, FALSE);
+	(void)do_map(2, buf, MODE_LANGMAP, FALSE);
     }
 
     p_cpo = save_cpo;
@@ -2597,7 +2597,7 @@ keymap_unload(void)
     for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
     {
 	vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s", kp[i].from);
-	(void)do_map(1, buf, LANGMAP, FALSE);
+	(void)do_map(1, buf, MODE_LANGMAP, FALSE);
     }
     keymap_clear(&curbuf->b_kmap_ga);
 
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1963,7 +1963,7 @@ win_line(
 			// In Insert mode only highlight a word that
 			// doesn't touch the cursor.
 			if (spell_hlf != HLF_COUNT
-				&& (State & INSERT) != 0
+				&& (State & MODE_INSERT)
 				&& wp->w_cursor.lnum == lnum
 				&& wp->w_cursor.col >=
 						    (colnr_T)(prev_ptr - line)
@@ -2595,7 +2595,7 @@ win_line(
 	if (p_imst == IM_ON_THE_SPOT
 		&& xic != NULL
 		&& lnum == wp->w_cursor.lnum
-		&& (State & INSERT)
+		&& (State & MODE_INSERT)
 		&& !p_imdisable
 		&& im_is_preediting()
 		&& draw_state == WL_LINE)
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -686,7 +686,7 @@ win_redr_ruler(win_T *wp, int always, in
     /*
      * Check if not in Insert mode and the line is empty (will show "0-1").
      */
-    if (!(State & INSERT)
+    if ((State & MODE_INSERT) == 0
 		&& *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE) == NUL)
 	empty_line = TRUE;
 
@@ -2834,7 +2834,7 @@ update_debug_sign(buf_T *buf, linenr_T l
     // Return when there is nothing to do, screen updating is already
     // happening (recursive call), messages on the screen or still starting up.
     if (!doit || updating_screen
-	    || State == ASKMORE || State == HITRETURN
+	    || State == MODE_ASKMORE || State == MODE_HITRETURN
 	    || msg_scrolled
 #ifdef FEAT_GUI
 	    || gui.starting
@@ -2925,7 +2925,8 @@ redraw_asap(int type)
     schar_T	*screenline2 = NULL;	// copy from ScreenLines2[]
 
     redraw_later(type);
-    if (msg_scrolled || (State != NORMAL && State != NORMAL_BUSY) || exiting)
+    if (msg_scrolled || (State != MODE_NORMAL && State != MODE_NORMAL_BUSY)
+								    || exiting)
 	return ret;
 
     // Allocate space to save the text displayed in the command line area.
@@ -3049,13 +3050,14 @@ redraw_after_callback(int call_update_sc
 {
     ++redrawing_for_callback;
 
-    if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
-	    || State == EXTERNCMD || State == CONFIRM || exmode_active)
+    if (State == MODE_HITRETURN || State == MODE_ASKMORE
+	    || State == MODE_SETWSIZE || State == MODE_EXTERNCMD
+	    || State == MODE_CONFIRM || exmode_active)
     {
 	if (do_message)
 	    repeat_message();
     }
-    else if (State & CMDLINE)
+    else if (State & MODE_CMDLINE)
     {
 #ifdef FEAT_WILDMENU
 	if (pum_visible())
@@ -3078,7 +3080,7 @@ redraw_after_callback(int call_update_sc
 	    redrawcmdline_ex(FALSE);
 	}
     }
-    else if (State & (NORMAL | INSERT | TERMINAL))
+    else if (State & (MODE_NORMAL | MODE_INSERT | MODE_TERMINAL))
     {
 	update_topline();
 	validate_cursor();
--- a/src/edit.c
+++ b/src/edit.c
@@ -142,7 +142,7 @@ edit(
     int		old_topfill = -1;
 #endif
     int		inserted_space = FALSE;     // just inserted a space
-    int		replaceState = REPLACE;
+    int		replaceState = MODE_REPLACE;
     int		nomove = FALSE;		    // don't move cursor on return
 #ifdef FEAT_JOB_CHANNEL
     int		cmdchar_todo = cmdchar;
@@ -218,7 +218,7 @@ edit(
 	    int save_state = State;
 
 	    curwin->w_cursor = save_cursor;
-	    State = INSERT;
+	    State = MODE_INSERT;
 	    check_cursor_col();
 	    State = save_state;
 	}
@@ -272,17 +272,17 @@ edit(
 
     if (cmdchar == 'R')
     {
-	State = REPLACE;
+	State = MODE_REPLACE;
     }
     else if (cmdchar == 'V' || cmdchar == 'v')
     {
-	State = VREPLACE;
-	replaceState = VREPLACE;
+	State = MODE_VREPLACE;
+	replaceState = MODE_VREPLACE;
 	orig_line_count = curbuf->b_ml.ml_line_count;
 	vr_lines_changed = 1;
     }
     else
-	State = INSERT;
+	State = MODE_INSERT;
 
     may_trigger_modechanged();
     stop_insert_mode = FALSE;
@@ -304,7 +304,7 @@ edit(
      * when hitting <Esc>.
      */
     if (curbuf->b_p_iminsert == B_IMODE_LMAP)
-	State |= LANGMAP;
+	State |= MODE_LANGMAP;
 #ifdef HAVE_INPUT_METHOD
     im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
 #endif
@@ -315,7 +315,7 @@ edit(
 #endif
 #ifdef FEAT_RIGHTLEFT
     // there is no reverse replace mode
-    revins_on = (State == INSERT && p_ri);
+    revins_on = (State == MODE_INSERT && p_ri);
     if (revins_on)
 	undisplay_dollar();
     revins_chars = 0;
@@ -1802,8 +1802,8 @@ undisplay_dollar(void)
 
 /*
  * Truncate the space at the end of a line.  This is to be used only in an
- * insert mode.  It handles fixing the replace stack for REPLACE and VREPLACE
- * modes.
+ * insert mode.  It handles fixing the replace stack for MODE_REPLACE and
+ * MODE_VREPLACE modes.
  */
     void
 truncate_spaces(char_u *line)
@@ -1820,9 +1820,9 @@ truncate_spaces(char_u *line)
 }
 
 /*
- * Backspace the cursor until the given column.  Handles REPLACE and VREPLACE
- * modes correctly.  May also be used when not in insert mode at all.
- * Will attempt not to go before "col" even when there is a composing
+ * Backspace the cursor until the given column.  Handles MODE_REPLACE and
+ * MODE_VREPLACE modes correctly.  May also be used when not in insert mode at
+ * all.  Will attempt not to go before "col" even when there is a composing
  * character.
  */
     void
@@ -1924,7 +1924,7 @@ get_literal(int noReduceKeys)
 	    break;
 
 #ifdef FEAT_CMDL_INFO
-	if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1)
+	if ((State & MODE_CMDLINE) == 0 && MB_BYTE2LEN_CHECK(nc) == 1)
 	    add_to_showcmd(nc);
 #endif
 	if (nc == 'x' || nc == 'X')
@@ -2099,7 +2099,7 @@ insertchar(
      * - Otherwise:
      *	 - Don't do this if inserting a blank
      *	 - Don't do this if an existing character is being replaced, unless
-     *	   we're in VREPLACE mode.
+     *	   we're in MODE_VREPLACE state.
      *	 - Do this if the cursor is not on the line where insert started
      *	 or - 'formatoptions' doesn't have 'l' or the line was not too long
      *	       before the insert.
@@ -2810,7 +2810,7 @@ cursor_up(
 		// If we entered a fold, move to the beginning, unless in
 		// Insert mode or when 'foldopen' contains "all": it will open
 		// in a moment.
-		if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL)))
+		if (n > 0 || !((State & MODE_INSERT) || (fdo_flags & FDO_ALL)))
 		    (void)hasFolding(lnum, &lnum, NULL);
 	    }
 	    if (lnum < 1)
@@ -3107,7 +3107,7 @@ replace_join(
 
 /*
  * Pop bytes from the replace stack until a NUL is found, and insert them
- * before the cursor.  Can only be used in REPLACE or VREPLACE mode.
+ * before the cursor.  Can only be used in MODE_REPLACE or MODE_VREPLACE state.
  */
     static void
 replace_pop_ins(void)
@@ -3115,7 +3115,7 @@ replace_pop_ins(void)
     int	    cc;
     int	    oldState = State;
 
-    State = NORMAL;			// don't want REPLACE here
+    State = MODE_NORMAL;			// don't want MODE_REPLACE here
     while ((cc = replace_pop()) > 0)
     {
 	mb_replace_pop_ins(cc);
@@ -3545,18 +3545,18 @@ ins_ctrl_g(void)
     static void
 ins_ctrl_hat(void)
 {
-    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+    if (map_to_exists_mode((char_u *)"", MODE_LANGMAP, FALSE))
     {
 	// ":lmap" mappings exists, Toggle use of ":lmap" mappings.
-	if (State & LANGMAP)
+	if (State & MODE_LANGMAP)
 	{
 	    curbuf->b_p_iminsert = B_IMODE_NONE;
-	    State &= ~LANGMAP;
+	    State &= ~MODE_LANGMAP;
 	}
 	else
 	{
 	    curbuf->b_p_iminsert = B_IMODE_LMAP;
-	    State |= LANGMAP;
+	    State |= MODE_LANGMAP;
 #ifdef HAVE_INPUT_METHOD
 	    im_set_active(FALSE);
 #endif
@@ -3574,7 +3574,7 @@ ins_ctrl_hat(void)
 	else
 	{
 	    curbuf->b_p_iminsert = B_IMODE_IM;
-	    State &= ~LANGMAP;
+	    State &= ~MODE_LANGMAP;
 	    im_set_active(TRUE);
 	}
     }
@@ -3704,12 +3704,12 @@ ins_esc(
     // Disable IM to allow typing English directly for Normal mode commands.
     // When ":lmap" is enabled don't change 'iminsert' (IM can be enabled as
     // well).
-    if (!(State & LANGMAP))
+    if (!(State & MODE_LANGMAP))
 	im_save_status(&curbuf->b_p_iminsert);
     im_set_active(FALSE);
 #endif
 
-    State = NORMAL;
+    State = MODE_NORMAL;
     may_trigger_modechanged();
     // need to position cursor again when on a TAB
     if (gchar_cursor() == TAB)
@@ -3760,7 +3760,7 @@ ins_ctrl_(void)
 	    ++curwin->w_cursor.col;
     }
     p_ri = !p_ri;
-    revins_on = (State == INSERT && p_ri);
+    revins_on = (State == MODE_INSERT && p_ri);
     if (revins_on)
     {
 	revins_scol = curwin->w_cursor.col;
@@ -3839,14 +3839,14 @@ ins_insert(int replaceState)
 #ifdef FEAT_EVAL
     set_vim_var_string(VV_INSERTMODE,
 		   (char_u *)((State & REPLACE_FLAG) ? "i"
-		          : replaceState == VREPLACE ? "v"
+		          : replaceState == MODE_VREPLACE ? "v"
 						     : "r"), 1);
 #endif
     ins_apply_autocmds(EVENT_INSERTCHANGE);
     if (State & REPLACE_FLAG)
-	State = INSERT | (State & LANGMAP);
+	State = MODE_INSERT | (State & MODE_LANGMAP);
     else
-	State = replaceState | (State & LANGMAP);
+	State = replaceState | (State & MODE_LANGMAP);
     may_trigger_modechanged();
     AppendCharToRedobuff(K_INS);
     showmode();
@@ -4119,20 +4119,20 @@ ins_bs(
 		dec_cursor();
 
 	    /*
-	     * In REPLACE mode we have to put back the text that was replaced
-	     * by the NL. On the replace stack is first a NUL-terminated
-	     * sequence of characters that were deleted and then the
-	     * characters that NL replaced.
+	     * In MODE_REPLACE mode we have to put back the text that was
+	     * replaced by the NL. On the replace stack is first a
+	     * NUL-terminated sequence of characters that were deleted and then
+	     * the characters that NL replaced.
 	     */
 	    if (State & REPLACE_FLAG)
 	    {
 		/*
-		 * Do the next ins_char() in NORMAL state, to
+		 * Do the next ins_char() in MODE_NORMAL state, to
 		 * prevent ins_char() from replacing characters and
 		 * avoiding showmatch().
 		 */
 		oldState = State;
-		State = NORMAL;
+		State = MODE_NORMAL;
 		/*
 		 * restore characters (blanks) deleted after cursor
 		 */
@@ -4943,7 +4943,7 @@ ins_tab(void)
     /*
      * Insert the first space with ins_char().	It will delete one char in
      * replace mode.  Insert the rest with ins_str(); it will not delete any
-     * chars.  For VREPLACE mode, we use ins_char() for all characters.
+     * chars.  For MODE_VREPLACE state, we use ins_char() for all characters.
      */
     ins_char(' ');
     while (--temp > 0)
@@ -4979,8 +4979,8 @@ ins_tab(void)
 	int		save_list = curwin->w_p_list;
 
 	/*
-	 * Get the current line.  For VREPLACE mode, don't make real changes
-	 * yet, just work on a copy of the line.
+	 * Get the current line.  For MODE_VREPLACE state, don't make real
+	 * changes yet, just work on a copy of the line.
 	 */
 	if (State & VREPLACE_FLAG)
 	{
@@ -5111,9 +5111,9 @@ ins_tab(void)
 	    cursor->col -= i;
 
 	    /*
-	     * In VREPLACE mode, we haven't changed anything yet.  Do it now by
-	     * backspacing over the changed spacing and then inserting the new
-	     * spacing.
+	     * In MODE_VREPLACE state, we haven't changed anything yet.  Do it
+	     * now by backspacing over the changed spacing and then inserting
+	     * the new spacing.
 	     */
 	    if (State & VREPLACE_FLAG)
 	    {
@@ -5159,7 +5159,7 @@ ins_eol(int c)
 	replace_push(NUL);
 
     /*
-     * In VREPLACE mode, a NL replaces the rest of the line, and starts
+     * In MODE_VREPLACE state, a NL replaces the rest of the line, and starts
      * replacing the next line, so we push all of the characters left on the
      * line onto the replace stack.  This is not done here though, it is done
      * in open_line().
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -10452,7 +10452,7 @@ f_visualmode(typval_T *argvars, typval_T
 f_wildmenumode(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
 {
 #ifdef FEAT_WILDMENU
-    if (wild_menu_showing || ((State & CMDLINE) && cmdline_pum_active()))
+    if (wild_menu_showing || ((State & MODE_CMDLINE) && cmdline_pum_active()))
 	rettv->vval.v_number = 1;
 #endif
 }
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -3182,7 +3182,7 @@ do_ecmd(
 	redraw_curbuf_later(NOT_VALID);	// redraw this buffer later
     }
 
-    if (p_im && (State & INSERT) == 0)
+    if (p_im && (State & MODE_INSERT) == 0)
 	need_start_insertmode = TRUE;
 
 #ifdef FEAT_AUTOCHDIR
@@ -3271,9 +3271,9 @@ ex_append(exarg_T *eap)
     if (empty && lnum == 1)
 	lnum = 0;
 
-    State = INSERT;		    // behave like in Insert mode
+    State = MODE_INSERT;		    // behave like in Insert mode
     if (curbuf->b_p_iminsert == B_IMODE_LMAP)
-	State |= LANGMAP;
+	State |= MODE_LANGMAP;
 
     for (;;)
     {
@@ -3308,9 +3308,9 @@ ex_append(exarg_T *eap)
 	{
 	    int save_State = State;
 
-	    // Set State to avoid the cursor shape to be set to INSERT mode
-	    // when getline() returns.
-	    State = CMDLINE;
+	    // Set State to avoid the cursor shape to be set to MODE_INSERT
+	    // state when getline() returns.
+	    State = MODE_CMDLINE;
 	    theline = eap->getline(
 #ifdef FEAT_EVAL
 		    eap->cstack->cs_looplevel > 0 ? -1 :
@@ -3366,7 +3366,7 @@ ex_append(exarg_T *eap)
 	    empty = FALSE;
 	}
     }
-    State = NORMAL;
+    State = MODE_NORMAL;
 
     if (eap->forceit)
 	curbuf->b_p_ai = !curbuf->b_p_ai;
@@ -4183,10 +4183,10 @@ ex_substitute(exarg_T *eap)
 		{
 		    int typed = 0;
 
-		    // change State to CONFIRM, so that the mouse works
+		    // change State to MODE_CONFIRM, so that the mouse works
 		    // properly
 		    save_State = State;
-		    State = CONFIRM;
+		    State = MODE_CONFIRM;
 		    setmouse();		// disable mouse in xterm
 		    curwin->w_cursor.col = regmatch.startpos[0].col;
 		    if (curwin->w_p_crb)
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -476,7 +476,7 @@ do_exmode(
 	exmode_active = EXMODE_VIM;
     else
 	exmode_active = EXMODE_NORMAL;
-    State = NORMAL;
+    State = MODE_NORMAL;
     may_trigger_modechanged();
 
     // When using ":global /pat/ visual" and then "Q" we return to continue
@@ -8328,7 +8328,7 @@ ex_redraw(exarg_T *eap)
     need_wait_return = FALSE;
 
     // When invoked from a callback or autocmd the command line may be active.
-    if (State & CMDLINE)
+    if (State & MODE_CMDLINE)
 	redrawcmdline();
 
     out_flush();
@@ -8676,7 +8676,7 @@ ex_startinsert(exarg_T *eap)
 
     // Ignore the command when already in Insert mode.  Inserting an
     // expression register that invokes a function can do this.
-    if (State & INSERT)
+    if (State & MODE_INSERT)
 	return;
 
     if (eap->cmdidx == CMD_startinsert)
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1150,16 +1150,16 @@ cmdline_erase_chars(
     static void
 cmdline_toggle_langmap(long *b_im_ptr)
 {
-    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+    if (map_to_exists_mode((char_u *)"", MODE_LANGMAP, FALSE))
     {
 	// ":lmap" mappings exists, toggle use of mappings.
-	State ^= LANGMAP;
+	State ^= MODE_LANGMAP;
 #ifdef HAVE_INPUT_METHOD
 	im_set_active(FALSE);	// Disable input method
 #endif
 	if (b_im_ptr != NULL)
 	{
-	    if (State & LANGMAP)
+	    if (State & MODE_LANGMAP)
 		*b_im_ptr = B_IMODE_LMAP;
 	    else
 		*b_im_ptr = B_IMODE_NONE;
@@ -1683,7 +1683,7 @@ getcmdline_int(
      */
     msg_scroll = FALSE;
 
-    State = CMDLINE;
+    State = MODE_CMDLINE;
 
     if (firstc == '/' || firstc == '?' || firstc == '@')
     {
@@ -1693,7 +1693,7 @@ getcmdline_int(
 	else
 	    b_im_ptr = &curbuf->b_p_imsearch;
 	if (*b_im_ptr == B_IMODE_LMAP)
-	    State |= LANGMAP;
+	    State |= MODE_LANGMAP;
 #ifdef HAVE_INPUT_METHOD
 	im_set_active(*b_im_ptr == B_IMODE_IM);
 #endif
@@ -3208,7 +3208,7 @@ cmdline_getvcol_cursor(void)
     static void
 redrawcmd_preedit(void)
 {
-    if ((State & CMDLINE)
+    if ((State & MODE_CMDLINE)
 	    && xic != NULL
 	    // && im_get_status()  doesn't work when using SCIM
 	    && !p_imdisable
@@ -4089,7 +4089,7 @@ get_cmdline_info(void)
     static cmdline_info_T *
 get_ccline_ptr(void)
 {
-    if ((State & CMDLINE) == 0)
+    if ((State & MODE_CMDLINE) == 0)
 	return NULL;
     if (ccline.cmdbuff != NULL)
 	return &ccline;
@@ -4451,8 +4451,8 @@ open_cmdwin(void)
     {
 	if (p_wc == TAB)
 	{
-	    add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
-	    add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
+	    add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", MODE_INSERT);
+	    add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", MODE_NORMAL);
 	}
 	set_option_value_give_err((char_u *)"ft",
 					       0L, (char_u *)"vim", OPT_LOCAL);
@@ -4495,7 +4495,7 @@ open_cmdwin(void)
     // No Ex mode here!
     exmode_active = 0;
 
-    State = NORMAL;
+    State = MODE_NORMAL;
     setmouse();
 
     // Reset here so it can be set by a CmdWinEnter autocommand.
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2945,7 +2945,7 @@ check_for_cryptkey(
     // When starting to edit a new file which does not have encryption, clear
     // the 'key' option, except when starting up (called with -x argument)
     else if (newfile && *curbuf->b_p_key != NUL && !starting)
-	set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
+	set_option_value_give_err((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
 
     return cryptkey;
 }
@@ -4264,7 +4264,8 @@ buf_check_timestamp(
 	    }
 	    else
 #endif
-	    if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned)
+	    if (State > MODE_NORMAL_BUSY || (State & MODE_CMDLINE)
+							     || already_warned)
 	    {
 		if (*mesg2 != NUL)
 		{
--- a/src/fold.c
+++ b/src/fold.c
@@ -1499,7 +1499,7 @@ foldMarkAdjust(
 	line2 = line1 - amount_after - 1;
     // If appending a line in Insert mode, it should be included in the fold
     // just above the line.
-    if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+    if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
 	--line1;
     foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after);
 }
@@ -1523,7 +1523,7 @@ foldMarkAdjustRecurse(
 
     // In Insert mode an inserted line at the top of a fold is considered part
     // of the fold, otherwise it isn't.
-    if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+    if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
 	top = line1 + 1;
     else
 	top = line1;
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1346,7 +1346,7 @@ ungetchars(int len)
     static void
 may_sync_undo(void)
 {
-    if ((!(State & (INSERT + CMDLINE)) || arrow_used)
+    if ((!(State & (MODE_INSERT | MODE_CMDLINE)) || arrow_used)
 					       && scriptin[curscript] == NULL)
 	u_sync(FALSE);
 }
@@ -1533,7 +1533,7 @@ openscript(
 	int	save_finish_op = finish_op;
 	int	save_msg_scroll = msg_scroll;
 
-	State = NORMAL;
+	State = MODE_NORMAL;
 	msg_scroll = FALSE;	// no msg scrolling in Normal mode
 	restart_edit = 0;	// don't go to Insert mode
 	p_im = FALSE;		// don't use 'insertmode'
@@ -2483,10 +2483,10 @@ handle_mapping(
 		|| (p_remap
 		    && (typebuf.tb_noremap[typebuf.tb_off]
 				    & (RM_NONE|RM_ABBR)) == 0))
-	    && !(p_paste && (State & (INSERT + CMDLINE)))
-	    && !(State == HITRETURN && (tb_c1 == CAR || tb_c1 == ' '))
-	    && State != ASKMORE
-	    && State != CONFIRM
+	    && !(p_paste && (State & (MODE_INSERT | MODE_CMDLINE)))
+	    && !(State == MODE_HITRETURN && (tb_c1 == CAR || tb_c1 == ' '))
+	    && State != MODE_ASKMORE
+	    && State != MODE_CONFIRM
 	    && !at_ins_compl_key())
     {
 #ifdef FEAT_GUI
@@ -2503,8 +2503,8 @@ handle_mapping(
 	    nolmaplen = 2;
 	else
 	{
-	    LANGMAP_ADJUST(tb_c1, (State & (CMDLINE | INSERT)) == 0
-					    && get_real_state() != SELECTMODE);
+	    LANGMAP_ADJUST(tb_c1, (State & (MODE_CMDLINE | MODE_INSERT)) == 0
+					   && get_real_state() != MODE_SELECT);
 	    nolmaplen = 0;
 	}
 #endif
@@ -2537,7 +2537,7 @@ handle_mapping(
 		    && (mp->m_mode & local_State)
 		    && !(mp->m_simplified && seenModifyOtherKeys
 						     && typebuf.tb_maplen == 0)
-		    && ((mp->m_mode & LANGMAP) == 0 || typebuf.tb_maplen == 0))
+		    && ((mp->m_mode & MODE_LANGMAP) == 0 || typebuf.tb_maplen == 0))
 	    {
 #ifdef FEAT_LANGMAP
 		int	nomap = nolmaplen;
@@ -2644,7 +2644,7 @@ handle_mapping(
     /*
      * Check for match with 'pastetoggle'
      */
-    if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
+    if (*p_pt != NUL && mp == NULL && (State & (MODE_INSERT | MODE_NORMAL)))
     {
 	for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen]; ++mlen)
 	    if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off + mlen])
@@ -2659,7 +2659,7 @@ handle_mapping(
 	    del_typebuf(mlen, 0); // remove the chars
 	    set_option_value_give_err((char_u *)"paste",
 						      (long)!p_paste, NULL, 0);
-	    if (!(State & INSERT))
+	    if (!(State & MODE_INSERT))
 	    {
 		msg_col = 0;
 		msg_row = Rows - 1;
@@ -2792,7 +2792,7 @@ handle_mapping(
 		    // to Visual mode temporarily.  Append K_SELECT to switch
 		    // back to Select mode.
 		    if (VIsual_active && VIsual_select
-					     && (current_menu->modes & VISUAL))
+					&& (current_menu->modes & MODE_VISUAL))
 		    {
 			VIsual_select = FALSE;
 			(void)ins_typebuf(K_SELECT_STRING,
@@ -2848,7 +2848,7 @@ handle_mapping(
 	if (++*mapdepth >= p_mmd)
 	{
 	    emsg(_(e_recursive_mapping));
-	    if (State & CMDLINE)
+	    if (State & MODE_CMDLINE)
 		redrawcmdline();
 	    else
 		setcursor();
@@ -2862,7 +2862,7 @@ handle_mapping(
 	 * In Select mode and a Visual mode mapping is used: Switch to Visual
 	 * mode temporarily.  Append K_SELECT to switch back to Select mode.
 	 */
-	if (VIsual_active && VIsual_select && (mp->m_mode & VISUAL))
+	if (VIsual_active && VIsual_select && (mp->m_mode & MODE_VISUAL))
 	{
 	    VIsual_select = FALSE;
 	    (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE, 0, TRUE, FALSE);
@@ -2913,7 +2913,7 @@ handle_mapping(
 		buf[2] = KE_IGNORE;
 		buf[3] = NUL;
 		map_str = vim_strsave(buf);
-		if (State & CMDLINE)
+		if (State & MODE_CMDLINE)
 		{
 		    // redraw the command below the error
 		    msg_didout = TRUE;
@@ -3139,7 +3139,7 @@ vgetorpeek(int advance)
 		     * really insert a CTRL-C.
 		     */
 		    if ((c || typebuf.tb_maplen)
-					      && (State & (INSERT + CMDLINE)))
+				     && (State & (MODE_INSERT | MODE_CMDLINE)))
 			c = ESC;
 		    else
 			c = Ctrl_C;
@@ -3223,7 +3223,7 @@ vgetorpeek(int advance)
 			&& !no_mapping
 			&& ex_normal_busy == 0
 			&& typebuf.tb_maplen == 0
-			&& (State & INSERT)
+			&& (State & MODE_INSERT)
 			&& (p_timeout
 			    || (keylen == KEYLEN_PART_KEY && p_ttimeout))
 			&& (c = inchar(typebuf.tb_buf + typebuf.tb_off
@@ -3239,12 +3239,12 @@ vgetorpeek(int advance)
 		    }
 #ifdef FEAT_GUI
 		    // may show a different cursor shape
-		    if (gui.in_use && State != NORMAL && !cmd_silent)
+		    if (gui.in_use && State != MODE_NORMAL && !cmd_silent)
 		    {
 			int	    save_State;
 
 			save_State = State;
-			State = NORMAL;
+			State = MODE_NORMAL;
 			gui_update_cursor(TRUE, FALSE);
 			State = save_State;
 			shape_changed = TRUE;
@@ -3353,13 +3353,13 @@ vgetorpeek(int advance)
 		    // For the cmdline window: Alternate between ESC and
 		    // CTRL-C: ESC for most situations and CTRL-C to close the
 		    // cmdline window.
-		    if (p_im && (State & INSERT))
+		    if (p_im && (State & MODE_INSERT))
 			c = Ctrl_L;
 #ifdef FEAT_TERMINAL
 		    else if (terminal_is_active())
 			c = K_CANCEL;
 #endif
-		    else if ((State & CMDLINE)
+		    else if ((State & MODE_CMDLINE)
 #ifdef FEAT_CMDWIN
 			    || (cmdwin_type > 0 && tc == ESC)
 #endif
@@ -3390,8 +3390,9 @@ vgetorpeek(int advance)
 		// changed text so far. Also for when 'lazyredraw' is set and
 		// redrawing was postponed because there was something in the
 		// input buffer (e.g., termresponse).
-		if (((State & INSERT) != 0 || p_lz) && (State & CMDLINE) == 0
-			  && advance && must_redraw != 0 && !need_wait_return)
+		if (((State & MODE_INSERT) != 0 || p_lz)
+			&& (State & MODE_CMDLINE) == 0
+			&& advance && must_redraw != 0 && !need_wait_return)
 		{
 		    update_screen(0);
 		    setcursor(); // put cursor back where it belongs
@@ -3408,11 +3409,12 @@ vgetorpeek(int advance)
 		c1 = 0;
 		if (typebuf.tb_len > 0 && advance && !exmode_active)
 		{
-		    if (((State & (NORMAL | INSERT)) || State == LANGMAP)
-			    && State != HITRETURN)
+		    if (((State & (MODE_NORMAL | MODE_INSERT))
+						      || State == MODE_LANGMAP)
+			    && State != MODE_HITRETURN)
 		    {
 			// this looks nice when typing a dead character map
-			if (State & INSERT
+			if (State & MODE_INSERT
 			    && ptr2cells(typebuf.tb_buf + typebuf.tb_off
 						   + typebuf.tb_len - 1) == 1)
 			{
@@ -3439,7 +3441,7 @@ vgetorpeek(int advance)
 		    }
 
 		    // this looks nice when typing a dead character map
-		    if ((State & CMDLINE)
+		    if ((State & MODE_CMDLINE)
 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
 			    && cmdline_star == 0
 #endif
@@ -3486,9 +3488,9 @@ vgetorpeek(int advance)
 #endif
 		if (c1 == 1)
 		{
-		    if (State & INSERT)
+		    if (State & MODE_INSERT)
 			edit_unputchar();
-		    if (State & CMDLINE)
+		    if (State & MODE_CMDLINE)
 			unputcmdline();
 		    else
 			setcursor();	// put cursor back where it belongs
@@ -3529,7 +3531,7 @@ vgetorpeek(int advance)
      *	 if we return an ESC to exit insert mode, the message is deleted
      *	 if we don't return an ESC but deleted the message before, redisplay it
      */
-    if (advance && p_smd && msg_silent == 0 && (State & INSERT))
+    if (advance && p_smd && msg_silent == 0 && (State & MODE_INSERT))
     {
 	if (c == ESC && !mode_deleted && !no_mapping && mode_displayed)
 	{
@@ -3617,7 +3619,7 @@ inchar(
      * recursive loop may result (write error in swapfile, hit-return, timeout
      * on char wait, flush swapfile, write error....).
      */
-    if (State != HITRETURN)
+    if (State != MODE_HITRETURN)
     {
 	did_outofmem_msg = FALSE;   // display out of memory message (again)
 	did_swapwrite_msg = FALSE;  // display swap file write error again
--- a/src/globals.h
+++ b/src/globals.h
@@ -977,7 +977,7 @@ EXTERN pos_T	Insstart;		// This is where
 EXTERN pos_T	Insstart_orig;
 
 /*
- * Stuff for VREPLACE mode.
+ * Stuff for MODE_VREPLACE state.
  */
 EXTERN int	orig_line_count INIT(= 0);  // Line count when "gR" started
 EXTERN int	vr_lines_changed INIT(= 0); // #Lines changed by "gR" so far
@@ -1095,14 +1095,14 @@ EXTERN guicolor_T	xim_bg_color INIT(= IN
 /*
  * "State" is the main state of Vim.
  * There are other variables that modify the state:
- * "Visual_mode"    When State is NORMAL or INSERT.
- * "finish_op"	    When State is NORMAL, after typing the operator and before
- *		    typing the motion command.
+ * "Visual_mode"    When State is MODE_NORMAL or MODE_INSERT.
+ * "finish_op"	    When State is MODE_NORMAL, after typing the operator and
+ *		    before typing the motion command.
  * "motion_force"   Last motion_force  from do_pending_operator()
  * "debug_mode"	    Debug mode.
  */
-EXTERN int	State INIT(= NORMAL);	// This is the current state of the
-					// command interpreter.
+EXTERN int	State INIT(= MODE_NORMAL);
+
 #ifdef FEAT_EVAL
 EXTERN int	debug_mode INIT(= FALSE);
 #endif
--- a/src/gui.c
+++ b/src/gui.c
@@ -1207,7 +1207,7 @@ gui_update_cursor(
 	else
 #endif
 	    shape = &shape_table[get_shape_idx(FALSE)];
-	if (State & LANGMAP)
+	if (State & MODE_LANGMAP)
 	    id = shape->id_lm;
 	else
 	    id = shape->id;
@@ -1580,7 +1580,7 @@ again:
      * At the "more" and ":confirm" prompt there is no redraw, put the cursor
      * at the last line here (why does it have to be one row too low?).
      */
-    if (State == ASKMORE || State == CONFIRM)
+    if (State == MODE_ASKMORE || State == MODE_CONFIRM)
 	gui.row = gui.num_rows;
 
     // Only comparing Rows and Columns may be sufficient, but let's stay on
@@ -3192,22 +3192,23 @@ button_set:
     // Determine which mouse settings to look for based on the current mode
     switch (get_real_state())
     {
-	case NORMAL_BUSY:
-	case OP_PENDING:
+	case MODE_NORMAL_BUSY:
+	case MODE_OP_PENDING:
 # ifdef FEAT_TERMINAL
-	case TERMINAL:
+	case MODE_TERMINAL:
 # endif
-	case NORMAL:		checkfor = MOUSE_NORMAL;	break;
-	case VISUAL:		checkfor = MOUSE_VISUAL;	break;
-	case SELECTMODE:	checkfor = MOUSE_VISUAL;	break;
-	case REPLACE:
-	case REPLACE+LANGMAP:
-	case VREPLACE:
-	case VREPLACE+LANGMAP:
-	case INSERT:
-	case INSERT+LANGMAP:	checkfor = MOUSE_INSERT;	break;
-	case ASKMORE:
-	case HITRETURN:		// At the more- and hit-enter prompt pass the
+	case MODE_NORMAL:	checkfor = MOUSE_NORMAL; break;
+	case MODE_VISUAL:	checkfor = MOUSE_VISUAL; break;
+	case MODE_SELECT:	checkfor = MOUSE_VISUAL; break;
+	case MODE_REPLACE:
+	case MODE_REPLACE | MODE_LANGMAP:
+	case MODE_VREPLACE:
+	case MODE_VREPLACE | MODE_LANGMAP:
+	case MODE_INSERT:
+	case MODE_INSERT | MODE_LANGMAP:
+				checkfor = MOUSE_INSERT; break;
+	case MODE_ASKMORE:
+	case MODE_HITRETURN:	// At the more- and hit-enter prompt pass the
 				// mouse event for a click on or below the
 				// message line.
 				if (Y_2_ROW(y) >= msg_row)
@@ -3220,8 +3221,8 @@ button_set:
 	     * On the command line, use the clipboard selection on all lines
 	     * but the command line.  But not when pasting.
 	     */
-	case CMDLINE:
-	case CMDLINE+LANGMAP:
+	case MODE_CMDLINE:
+	case MODE_CMDLINE | MODE_LANGMAP:
 	    if (Y_2_ROW(y) < cmdline_row && button != MOUSE_MIDDLE)
 		checkfor = MOUSE_NONE;
 	    else
@@ -3238,7 +3239,8 @@ button_set:
      * modes.  Don't do this when dragging the status line, or extending a
      * Visual selection.
      */
-    if ((State == NORMAL || State == NORMAL_BUSY || (State & INSERT))
+    if ((State == MODE_NORMAL || State == MODE_NORMAL_BUSY
+						      || (State & MODE_INSERT))
 	    && Y_2_ROW(y) >= topframe->fr_height + firstwin->w_winrow
 	    && button != MOUSE_DRAG
 # ifdef FEAT_MOUSESHAPE
@@ -3270,7 +3272,7 @@ button_set:
     if (!mouse_has(checkfor) || checkfor == MOUSE_COMMAND)
     {
 	// Don't do modeless selection in Visual mode.
-	if (checkfor != MOUSE_NONEF && VIsual_active && (State & NORMAL))
+	if (checkfor != MOUSE_NONEF && VIsual_active && (State & MODE_NORMAL))
 	    return;
 
 	/*
@@ -3291,7 +3293,7 @@ button_set:
 	{
 	    if (clip_star.state == SELECT_CLEARED)
 	    {
-		if (State & CMDLINE)
+		if (State & MODE_CMDLINE)
 		{
 		    col = msg_col;
 		    row = msg_row;
@@ -4086,17 +4088,17 @@ gui_drag_scrollbar(scrollbar_T *sb, long
 #ifdef USE_ON_FLY_SCROLL
 	current_scrollbar = sb_num;
 	scrollbar_value = value;
-	if (State & NORMAL)
+	if (State & MODE_NORMAL)
 	{
 	    gui_do_scroll();
 	    setcursor();
 	}
-	else if (State & INSERT)
+	else if (State & MODE_INSERT)
 	{
 	    ins_scroll();
 	    setcursor();
 	}
-	else if (State & CMDLINE)
+	else if (State & MODE_CMDLINE)
 	{
 	    if (msg_scrolled == 0)
 	    {
@@ -4131,11 +4133,11 @@ gui_drag_scrollbar(scrollbar_T *sb, long
 #ifdef USE_ON_FLY_SCROLL
 	scrollbar_value = value;
 
-	if (State & NORMAL)
+	if (State & MODE_NORMAL)
 	    gui_do_horiz_scroll(scrollbar_value, FALSE);
-	else if (State & INSERT)
+	else if (State & MODE_INSERT)
 	    ins_horscroll();
-	else if (State & CMDLINE)
+	else if (State & MODE_CMDLINE)
 	{
 	    if (msg_scrolled == 0)
 	    {
@@ -4890,8 +4892,8 @@ gui_mouse_focus(int x, int y)
     // Only handle this when 'mousefocus' set and ...
     if (p_mousef
 	    && !hold_gui_events		// not holding events
-	    && (State & (NORMAL|INSERT))// Normal/Visual/Insert mode
-	    && State != HITRETURN	// but not hit-return prompt
+	    && (State & (MODE_NORMAL | MODE_INSERT))// Normal/Visual/Insert mode
+	    && State != MODE_HITRETURN	// but not hit-return prompt
 	    && msg_scrolled == 0	// no scrolled message
 	    && !need_mouse_correct	// not moving the pointer
 	    && gui.in_focus)		// gvim in focus
@@ -5022,7 +5024,7 @@ xy2win(int x, int y, mouse_find_T popup)
     if (wp == NULL)
 	return NULL;
 #ifdef FEAT_MOUSESHAPE
-    if (State == HITRETURN || State == ASKMORE)
+    if (State == MODE_HITRETURN || State == MODE_ASKMORE)
     {
 	if (Y_2_ROW(y) >= msg_row)
 	    update_mouseshape(SHAPE_IDX_MOREL);
@@ -5031,10 +5033,10 @@ xy2win(int x, int y, mouse_find_T popup)
     }
     else if (row > wp->w_height)	// below status line
 	update_mouseshape(SHAPE_IDX_CLINE);
-    else if (!(State & CMDLINE) && wp->w_vsep_width > 0 && col == wp->w_width
+    else if (!(State & MODE_CMDLINE) && wp->w_vsep_width > 0 && col == wp->w_width
 	    && (row != wp->w_height || !stl_connected(wp)) && msg_scrolled == 0)
 	update_mouseshape(SHAPE_IDX_VSEP);
-    else if (!(State & CMDLINE) && wp->w_status_height > 0
+    else if (!(State & MODE_CMDLINE) && wp->w_status_height > 0
 				  && row == wp->w_height && msg_scrolled == 0)
 	update_mouseshape(SHAPE_IDX_STATUS);
     else
@@ -5454,7 +5456,7 @@ gui_do_findrepl(
     // syntax HL if we were busy redrawing.
     did_emsg = save_did_emsg;
 
-    if (State & (NORMAL | INSERT))
+    if (State & (MODE_NORMAL | MODE_INSERT))
     {
 	gui_update_screen();		// update the screen
 	msg_didout = 0;			// overwrite any message
@@ -5558,7 +5560,7 @@ gui_handle_drop(
      * When the cursor is at the command line, add the file names to the
      * command line, don't edit the files.
      */
-    if (State & CMDLINE)
+    if (State & MODE_CMDLINE)
     {
 	shorten_filenames(fnames, count);
 	for (i = 0; i < count; ++i)
--- a/src/gui_gtk.c
+++ b/src/gui_gtk.c
@@ -691,7 +691,7 @@ menu_item_select(GtkWidget *widget UNUSE
     char_u	*tooltip;
     static int	did_msg = FALSE;
 
-    if (State & CMDLINE)
+    if (State & MODE_CMDLINE)
 	return;
     menu = (vimmenu_T *)data;
     tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -1956,7 +1956,8 @@ process_message(void)
 	    }
 	    // In modes where we are not typing, dead keys should behave
 	    // normally
-	    else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE)))
+	    else if ((get_real_state()
+			    & (MODE_INSERT | MODE_CMDLINE | MODE_SELECT)) == 0)
 	    {
 		outputDeadKey_rePost(msg);
 		return;
@@ -4603,7 +4604,7 @@ destroy_sizing_tip(void)
     if (((UINT) HIWORD(wParam)
 		& (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP)))
 	    == MF_HILITE
-	    && (State & CMDLINE) == 0)
+	    && (State & MODE_CMDLINE) == 0)
     {
 	UINT	    idButton;
 	vimmenu_T   *pMenu;
@@ -5593,8 +5594,8 @@ gui_mch_set_sp_color(guicolor_T color)
 		im_set_position(gui.row, gui.col);
 
 		// Disable langmap
-		State &= ~LANGMAP;
-		if (State & INSERT)
+		State &= ~MODE_LANGMAP;
+		if (State & MODE_INSERT)
 		{
 # if defined(FEAT_KEYMAP)
 		    // Unshown 'keymap' in status lines
--- a/src/gui_xim.c
+++ b/src/gui_xim.c
@@ -156,7 +156,7 @@ static int xim_has_preediting INIT(= FAL
     static void
 init_preedit_start_col(void)
 {
-    if (State & CMDLINE)
+    if (State & MODE_CMDLINE)
 	preedit_start_col = cmdline_getvcol_cursor();
     else if (curwin != NULL && curwin->w_buffer != NULL)
 	getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL);
@@ -420,7 +420,7 @@ im_delete_preedit(void)
 	return;
     }
 
-    if (State & NORMAL
+    if (State & MODE_NORMAL
 #ifdef FEAT_TERMINAL
 	    && !term_use_loop()
 #endif
@@ -446,10 +446,10 @@ im_correct_cursor(int num_move_back)
 {
     char_u backkey[] = {CSI, 'k', 'l'};
 
-    if (State & NORMAL)
+    if (State & MODE_NORMAL)
 	return;
 #  ifdef FEAT_RIGHTLEFT
-    if ((State & CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl)
+    if ((State & MODE_CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl)
 	backkey[2] = 'r';
 #  endif
     for (; num_move_back > 0; --num_move_back)
@@ -471,7 +471,7 @@ im_show_info(void)
     vgetc_busy = TRUE;
     showmode();
     vgetc_busy = old_vgetc_busy;
-    if ((State & NORMAL) || (State & INSERT))
+    if ((State & MODE_NORMAL) || (State & MODE_INSERT))
 	setcursor();
     out_flush();
 }
@@ -1078,7 +1078,8 @@ xim_queue_key_press_event(GdkEventKey *e
     // gtk_im_context_filter_keypress() in Normal mode.
     // And while doing :sh too.
     if (xic != NULL && !p_imdisable
-		    && (State & (INSERT | CMDLINE | NORMAL | EXTERNCMD)) != 0)
+		    && (State & (MODE_INSERT | MODE_CMDLINE
+					      | MODE_NORMAL | MODE_EXTERNCMD)))
     {
 	// Filter 'imactivatekey' and map it to CTRL-^.  This way, Vim is
 	// always aware of the current status of IM, and can even emulate
@@ -1102,21 +1103,21 @@ xim_queue_key_press_event(GdkEventKey *e
 	    if (event->type != GDK_KEY_PRESS)
 		return TRUE;
 
-	    if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE))
+	    if (map_to_exists_mode((char_u *)"", MODE_LANGMAP, FALSE))
 	    {
 		im_set_active(FALSE);
 
 		// ":lmap" mappings exists, toggle use of mappings.
-		State ^= LANGMAP;
-		if (State & LANGMAP)
+		State ^= MODE_LANGMAP;
+		if (State & MODE_LANGMAP)
 		{
 		    curbuf->b_p_iminsert = B_IMODE_NONE;
-		    State &= ~LANGMAP;
+		    State &= ~MODE_LANGMAP;
 		}
 		else
 		{
 		    curbuf->b_p_iminsert = B_IMODE_LMAP;
-		    State |= LANGMAP;
+		    State |= MODE_LANGMAP;
 		}
 		return TRUE;
 	    }
--- a/src/indent.c
+++ b/src/indent.c
@@ -828,7 +828,7 @@ get_number_indent(linenr_T lnum)
     pos.lnum = 0;
 
     // In format_lines() (i.e. not insert mode), fo+=q is needed too...
-    if ((State & INSERT) || has_format_option(FO_Q_COMS))
+    if ((State & MODE_INSERT) || has_format_option(FO_Q_COMS))
 	lead_len = get_leader_len(ml_get(lnum), NULL, FALSE, TRUE);
 
     regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
@@ -1276,7 +1276,7 @@ change_indent(
     colnr_T	orig_col = 0;		// init for GCC
     char_u	*new_line, *orig_line = NULL;	// init for GCC
 
-    // VREPLACE mode needs to know what the line was like before changing
+    // MODE_VREPLACE state needs to know what the line was like before changing
     if (State & VREPLACE_FLAG)
     {
 	orig_line = vim_strsave(ml_get_curline());  // Deal with NULL below
@@ -1318,7 +1318,7 @@ change_indent(
 
 	// Avoid being called recursively.
 	if (State & VREPLACE_FLAG)
-	    State = INSERT;
+	    State = MODE_INSERT;
 	shift_line(type == INDENT_DEC, round, 1, call_changed_bytes);
 	State = save_State;
     }
@@ -1339,7 +1339,7 @@ change_indent(
 	    insstart_less = MAXCOL;
 	new_cursor_col += curwin->w_cursor.col;
     }
-    else if (!(State & INSERT))
+    else if (!(State & MODE_INSERT))
 	new_cursor_col = curwin->w_cursor.col;
     else
     {
@@ -1397,7 +1397,7 @@ change_indent(
     changed_cline_bef_curs();
 
     // May have to adjust the start of the insert.
-    if (State & INSERT)
+    if (State & MODE_INSERT)
     {
 	if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0)
 	{
@@ -1412,9 +1412,9 @@ change_indent(
 	    ai_col -= insstart_less;
     }
 
-    // For REPLACE mode, may have to fix the replace stack, if it's possible.
-    // If the number of characters before the cursor decreased, need to pop a
-    // few characters from the replace stack.
+    // For MODE_REPLACE state, may have to fix the replace stack, if it's
+    // possible.  If the number of characters before the cursor decreased, need
+    // to pop a few characters from the replace stack.
     // If the number of characters before the cursor increased, need to push a
     // few NULs onto the replace stack.
     if (REPLACE_NORMAL(State) && start_col >= 0)
@@ -1436,9 +1436,9 @@ change_indent(
 	}
     }
 
-    // For VREPLACE mode, we also have to fix the replace stack.  In this case
-    // it is always possible because we backspace over the whole line and then
-    // put it back again the way we wanted it.
+    // For MODE_VREPLACE state, we also have to fix the replace stack.  In this
+    // case it is always possible because we backspace over the whole line and
+    // then put it back again the way we wanted it.
     if (State & VREPLACE_FLAG)
     {
 	// If orig_line didn't allocate, just return.  At least we did the job,
@@ -1894,7 +1894,7 @@ get_expr_indent(void)
     // Pretend to be in Insert mode, allow cursor past end of line for "o"
     // command.
     save_State = State;
-    State = INSERT;
+    State = MODE_INSERT;
     curwin->w_cursor = save_pos;
     curwin->w_curswant = save_curswant;
     curwin->w_set_curswant = save_set_curswant;
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -2883,7 +2883,7 @@ f_complete(typval_T *argvars, typval_T *
 		|| check_for_list_arg(argvars, 1) == FAIL))
 	return;
 
-    if ((State & INSERT) == 0)
+    if ((State & MODE_INSERT) == 0)
     {
 	emsg(_(e_complete_can_only_be_used_in_insert_mode));
 	return;
--- a/src/macros.h
+++ b/src/macros.h
@@ -216,7 +216,7 @@
 
 #ifdef FEAT_RIGHTLEFT
     // Whether to draw the vertical bar on the right side of the cell.
-# define CURSOR_BAR_RIGHT (curwin->w_p_rl && (!(State & CMDLINE) || cmdmsg_rl))
+# define CURSOR_BAR_RIGHT (curwin->w_p_rl && (!(State & MODE_CMDLINE) || cmdmsg_rl))
 #endif
 
 /*
--- a/src/main.c
+++ b/src/main.c
@@ -1181,7 +1181,7 @@ main_loop(
     // exits while Vim is running in a console.
     if (!cmdwin && !noexmode && SETJMP(x_jump_env))
     {
-	State = NORMAL;
+	State = MODE_NORMAL;
 	VIsual_active = FALSE;
 	got_int = TRUE;
 	need_wait_return = FALSE;
@@ -1239,7 +1239,7 @@ main_loop(
 		// Typed two CTRL-C in a row: go back to ex mode as if "Q" was
 		// used and keep "got_int" set, so that it aborts ":g".
 		exmode_active = EXMODE_NORMAL;
-		State = NORMAL;
+		State = MODE_NORMAL;
 	    }
 	    else if (!global_busy || !exmode_active)
 	    {
--- a/src/map.c
+++ b/src/map.c
@@ -31,7 +31,7 @@ static int		maphash_valid = FALSE;
  * Returns a value between 0 and 255, index in maphash.
  * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
  */
-#define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + SELECTMODE + OP_PENDING + TERMINAL)) ? (c1) : ((c1) ^ 0x80))
+#define MAP_HASH(mode, c1) (((mode) & (MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING | MODE_TERMINAL)) ? (c1) : ((c1) ^ 0x80))
 
 /*
  * Get the start of the hashed map list for "state" and first character "c".
@@ -101,32 +101,33 @@ map_mode_to_chars(int mode)
 
     ga_init2(&mapmode, 1, 7);
 
-    if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
+    if ((mode & (MODE_INSERT | MODE_CMDLINE)) == (MODE_INSERT | MODE_CMDLINE))
 	ga_append(&mapmode, '!');			// :map!
-    else if (mode & INSERT)
+    else if (mode & MODE_INSERT)
 	ga_append(&mapmode, 'i');			// :imap
-    else if (mode & LANGMAP)
+    else if (mode & MODE_LANGMAP)
 	ga_append(&mapmode, 'l');			// :lmap
-    else if (mode & CMDLINE)
+    else if (mode & MODE_CMDLINE)
 	ga_append(&mapmode, 'c');			// :cmap
-    else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
-				 == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
+    else if ((mode
+		 & (MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING))
+		== (MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING))
 	ga_append(&mapmode, ' ');			// :map
     else
     {
-	if (mode & NORMAL)
+	if (mode & MODE_NORMAL)
 	    ga_append(&mapmode, 'n');			// :nmap
-	if (mode & OP_PENDING)
+	if (mode & MODE_OP_PENDING)
 	    ga_append(&mapmode, 'o');			// :omap
-	if (mode & TERMINAL)
+	if (mode & MODE_TERMINAL)
 	    ga_append(&mapmode, 't');			// :tmap
-	if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
+	if ((mode & (MODE_VISUAL | MODE_SELECT)) == (MODE_VISUAL | MODE_SELECT))
 	    ga_append(&mapmode, 'v');			// :vmap
 	else
 	{
-	    if (mode & VISUAL)
+	    if (mode & MODE_VISUAL)
 		ga_append(&mapmode, 'x');		// :xmap
-	    if (mode & SELECTMODE)
+	    if (mode & MODE_SELECT)
 		ga_append(&mapmode, 's');		// :smap
 	}
     }
@@ -297,21 +298,21 @@ map_add(
  * arg is pointer to any arguments. Note: arg cannot be a read-only string,
  * it will be modified.
  *
- * for :map   mode is NORMAL + VISUAL + SELECTMODE + OP_PENDING
- * for :map!  mode is INSERT + CMDLINE
- * for :cmap  mode is CMDLINE
- * for :imap  mode is INSERT
- * for :lmap  mode is LANGMAP
- * for :nmap  mode is NORMAL
- * for :vmap  mode is VISUAL + SELECTMODE
- * for :xmap  mode is VISUAL
- * for :smap  mode is SELECTMODE
- * for :omap  mode is OP_PENDING
- * for :tmap  mode is TERMINAL
+ * for :map   mode is MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING
+ * for :map!  mode is MODE_INSERT | MODE_CMDLINE
+ * for :cmap  mode is MODE_CMDLINE
+ * for :imap  mode is MODE_INSERT
+ * for :lmap  mode is MODE_LANGMAP
+ * for :nmap  mode is MODE_NORMAL
+ * for :vmap  mode is MODE_VISUAL | MODE_SELECT
+ * for :xmap  mode is MODE_VISUAL
+ * for :smap  mode is MODE_SELECT
+ * for :omap  mode is MODE_OP_PENDING
+ * for :tmap  mode is MODE_TERMINAL
  *
- * for :abbr  mode is INSERT + CMDLINE
- * for :iabbr mode is INSERT
- * for :cabbr mode is CMDLINE
+ * for :abbr  mode is MODE_INSERT | MODE_CMDLINE
+ * for :iabbr mode is MODE_INSERT
+ * for :cabbr mode is MODE_CMDLINE
  *
  * Return 0 for success
  *	  1 for invalid arguments
@@ -872,30 +873,31 @@ get_map_mode(char_u **cmdp, int forceit)
     p = *cmdp;
     modec = *p++;
     if (modec == 'i')
-	mode = INSERT;				// :imap
+	mode = MODE_INSERT;				// :imap
     else if (modec == 'l')
-	mode = LANGMAP;				// :lmap
+	mode = MODE_LANGMAP;				// :lmap
     else if (modec == 'c')
-	mode = CMDLINE;				// :cmap
+	mode = MODE_CMDLINE;				// :cmap
     else if (modec == 'n' && *p != 'o')		    // avoid :noremap
-	mode = NORMAL;				// :nmap
+	mode = MODE_NORMAL;				// :nmap
     else if (modec == 'v')
-	mode = VISUAL + SELECTMODE;		// :vmap
+	mode = MODE_VISUAL | MODE_SELECT;		// :vmap
     else if (modec == 'x')
-	mode = VISUAL;				// :xmap
+	mode = MODE_VISUAL;				// :xmap
     else if (modec == 's')
-	mode = SELECTMODE;			// :smap
+	mode = MODE_SELECT;			// :smap
     else if (modec == 'o')
-	mode = OP_PENDING;			// :omap
+	mode = MODE_OP_PENDING;			// :omap
     else if (modec == 't')
-	mode = TERMINAL;			// :tmap
+	mode = MODE_TERMINAL;			// :tmap
     else
     {
 	--p;
 	if (forceit)
-	    mode = INSERT + CMDLINE;		// :map !
+	    mode = MODE_INSERT | MODE_CMDLINE;		// :map !
 	else
-	    mode = VISUAL + SELECTMODE + NORMAL + OP_PENDING;// :map
+	    mode = MODE_VISUAL | MODE_SELECT | MODE_NORMAL | MODE_OP_PENDING;
+							// :map
     }
 
     *cmdp = p;
@@ -1002,21 +1004,21 @@ mode_str2flags(char_u *modechars)
     int		mode = 0;
 
     if (vim_strchr(modechars, 'n') != NULL)
-	mode |= NORMAL;
+	mode |= MODE_NORMAL;
     if (vim_strchr(modechars, 'v') != NULL)
-	mode |= VISUAL + SELECTMODE;
+	mode |= MODE_VISUAL | MODE_SELECT;
     if (vim_strchr(modechars, 'x') != NULL)
-	mode |= VISUAL;
+	mode |= MODE_VISUAL;
     if (vim_strchr(modechars, 's') != NULL)
-	mode |= SELECTMODE;
+	mode |= MODE_SELECT;
     if (vim_strchr(modechars, 'o') != NULL)
-	mode |= OP_PENDING;
+	mode |= MODE_OP_PENDING;
     if (vim_strchr(modechars, 'i') != NULL)
-	mode |= INSERT;
+	mode |= MODE_INSERT;
     if (vim_strchr(modechars, 'l') != NULL)
-	mode |= LANGMAP;
+	mode |= MODE_LANGMAP;
     if (vim_strchr(modechars, 'c') != NULL)
-	mode |= CMDLINE;
+	mode |= MODE_CMDLINE;
 
     return mode;
 }
@@ -1192,9 +1194,10 @@ set_context_in_map_cmd(
 	    expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
 	else
 	{
-	    expand_mapmodes = INSERT + CMDLINE;
+	    expand_mapmodes = MODE_INSERT | MODE_CMDLINE;
 	    if (!isabbrev)
-		expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING;
+		expand_mapmodes += MODE_VISUAL | MODE_SELECT | MODE_NORMAL
+							     | MODE_OP_PENDING;
 	}
 	expand_isabbrev = isabbrev;
 	xp->xp_context = EXPAND_MAPPINGS;
@@ -1864,75 +1867,76 @@ makemap(
 		    cmd = "map";
 		switch (mp->m_mode)
 		{
-		    case NORMAL + VISUAL + SELECTMODE + OP_PENDING:
+		    case MODE_NORMAL | MODE_VISUAL | MODE_SELECT
+							     | MODE_OP_PENDING:
 			break;
-		    case NORMAL:
+		    case MODE_NORMAL:
 			c1 = 'n';
 			break;
-		    case VISUAL:
+		    case MODE_VISUAL:
 			c1 = 'x';
 			break;
-		    case SELECTMODE:
+		    case MODE_SELECT:
 			c1 = 's';
 			break;
-		    case OP_PENDING:
+		    case MODE_OP_PENDING:
 			c1 = 'o';
 			break;
-		    case NORMAL + VISUAL:
+		    case MODE_NORMAL | MODE_VISUAL:
 			c1 = 'n';
 			c2 = 'x';
 			break;
-		    case NORMAL + SELECTMODE:
+		    case MODE_NORMAL | MODE_SELECT:
 			c1 = 'n';
 			c2 = 's';
 			break;
-		    case NORMAL + OP_PENDING:
+		    case MODE_NORMAL | MODE_OP_PENDING:
 			c1 = 'n';
 			c2 = 'o';
 			break;
-		    case VISUAL + SELECTMODE:
+		    case MODE_VISUAL | MODE_SELECT:
 			c1 = 'v';
 			break;
-		    case VISUAL + OP_PENDING:
+		    case MODE_VISUAL | MODE_OP_PENDING:
 			c1 = 'x';
 			c2 = 'o';
 			break;
-		    case SELECTMODE + OP_PENDING:
+		    case MODE_SELECT | MODE_OP_PENDING:
 			c1 = 's';
 			c2 = 'o';
 			break;
-		    case NORMAL + VISUAL + SELECTMODE:
+		    case MODE_NORMAL | MODE_VISUAL | MODE_SELECT:
 			c1 = 'n';
 			c2 = 'v';
 			break;
-		    case NORMAL + VISUAL + OP_PENDING:
+		    case MODE_NORMAL | MODE_VISUAL | MODE_OP_PENDING:
 			c1 = 'n';
 			c2 = 'x';
 			c3 = 'o';
 			break;
-		    case NORMAL + SELECTMODE + OP_PENDING:
+		    case MODE_NORMAL | MODE_SELECT | MODE_OP_PENDING:
 			c1 = 'n';
 			c2 = 's';
 			c3 = 'o';
 			break;
-		    case VISUAL + SELECTMODE + OP_PENDING:
+		    case MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING:
 			c1 = 'v';
 			c2 = 'o';
 			break;
-		    case CMDLINE + INSERT:
+		    case MODE_CMDLINE | MODE_INSERT:
 			if (!abbr)
 			    cmd = "map!";
 			break;
-		    case CMDLINE:
+		    case MODE_CMDLINE:
 			c1 = 'c';
 			break;
-		    case INSERT:
+		    case MODE_INSERT:
 			c1 = 'i';
 			break;
-		    case LANGMAP:
+		    case MODE_LANGMAP:
 			c1 = 'l';
 			break;
-		    case TERMINAL:
+		    case MODE_TERMINAL:
 			c1 = 't';
 			break;
 		    default:
@@ -2495,9 +2499,10 @@ get_map_mode_string(char_u *mode_string,
     int		mode = 0;
     int		tmode;
     int		modec;
-    const int	MASK_V = VISUAL + SELECTMODE;
-    const int	MASK_MAP = VISUAL + SELECTMODE + NORMAL + OP_PENDING;
-    const int	MASK_BANG = INSERT + CMDLINE;
+    const int	MASK_V = MODE_VISUAL | MODE_SELECT;
+    const int	MASK_MAP = MODE_VISUAL | MODE_SELECT | MODE_NORMAL
+							     | MODE_OP_PENDING;
+    const int	MASK_BANG = MODE_INSERT | MODE_CMDLINE;
 
     if (*p == NUL)
 	p = (char_u *)" ";	// compatibility
@@ -2505,14 +2510,14 @@ get_map_mode_string(char_u *mode_string,
     {
 	switch (modec)
 	{
-	    case 'i': tmode = INSERT;		break;
-	    case 'l': tmode = LANGMAP;		break;
-	    case 'c': tmode = CMDLINE;		break;
-	    case 'n': tmode = NORMAL;		break;
-	    case 'x': tmode = VISUAL;		break;
-	    case 's': tmode = SELECTMODE;	break;
-	    case 'o': tmode = OP_PENDING;	break;
-	    case 't': tmode = TERMINAL;		break;
+	    case 'i': tmode = MODE_INSERT;	break;
+	    case 'l': tmode = MODE_LANGMAP;	break;
+	    case 'c': tmode = MODE_CMDLINE;	break;
+	    case 'n': tmode = MODE_NORMAL;	break;
+	    case 'x': tmode = MODE_VISUAL;	break;
+	    case 's': tmode = MODE_SELECT;	break;
+	    case 'o': tmode = MODE_OP_PENDING;	break;
+	    case 't': tmode = MODE_TERMINAL;	break;
 	    case 'v': tmode = MASK_V;		break;
 	    case '!': tmode = MASK_BANG;	break;
 	    case ' ': tmode = MASK_MAP;		break;
@@ -2672,7 +2677,7 @@ f_mapset(typval_T *argvars, typval_T *re
 
 #if defined(MSWIN) || defined(MACOS_X)
 
-# define VIS_SEL	(VISUAL+SELECTMODE)	// abbreviation
+# define VIS_SEL	(MODE_VISUAL | MODE_SELECT)	// abbreviation
 
 /*
  * Default mappings for some often used keys.
@@ -2688,9 +2693,9 @@ struct initmap
 static struct initmap initmappings[] =
 {
 	// paste, copy and cut
-	{(char_u *)"<S-Insert> \"*P", NORMAL},
+	{(char_u *)"<S-Insert> \"*P", MODE_NORMAL},
 	{(char_u *)"<S-Insert> \"-d\"*P", VIS_SEL},
-	{(char_u *)"<S-Insert> <C-R><C-O>*", INSERT+CMDLINE},
+	{(char_u *)"<S-Insert> <C-R><C-O>*", MODE_INSERT | MODE_CMDLINE},
 	{(char_u *)"<C-Insert> \"*y", VIS_SEL},
 	{(char_u *)"<S-Del> \"*d", VIS_SEL},
 	{(char_u *)"<C-Del> \"*d", VIS_SEL},
@@ -2703,24 +2708,24 @@ static struct initmap initmappings[] =
 // Use the Windows (CUA) keybindings. (Console)
 static struct initmap cinitmappings[] =
 {
-	{(char_u *)"\316w <C-Home>", NORMAL+VIS_SEL},
-	{(char_u *)"\316w <C-Home>", INSERT+CMDLINE},
-	{(char_u *)"\316u <C-End>", NORMAL+VIS_SEL},
-	{(char_u *)"\316u <C-End>", INSERT+CMDLINE},
+	{(char_u *)"\316w <C-Home>", MODE_NORMAL | VIS_SEL},
+	{(char_u *)"\316w <C-Home>", MODE_INSERT | MODE_CMDLINE},
+	{(char_u *)"\316u <C-End>", MODE_NORMAL | VIS_SEL},
+	{(char_u *)"\316u <C-End>", MODE_INSERT | MODE_CMDLINE},
 
 	// paste, copy and cut
 #  ifdef FEAT_CLIPBOARD
-	{(char_u *)"\316\324 \"*P", NORMAL},	    // SHIFT-Insert is "*P
+	{(char_u *)"\316\324 \"*P", MODE_NORMAL},   // SHIFT-Insert is "*P
 	{(char_u *)"\316\324 \"-d\"*P", VIS_SEL},   // SHIFT-Insert is "-d"*P
-	{(char_u *)"\316\324 \022\017*", INSERT},  // SHIFT-Insert is ^R^O*
+	{(char_u *)"\316\324 \022\017*", MODE_INSERT},  // SHIFT-Insert is ^R^O*
 	{(char_u *)"\316\325 \"*y", VIS_SEL},	    // CTRL-Insert is "*y
 	{(char_u *)"\316\327 \"*d", VIS_SEL},	    // SHIFT-Del is "*d
 	{(char_u *)"\316\330 \"*d", VIS_SEL},	    // CTRL-Del is "*d
 	{(char_u *)"\030 \"*d", VIS_SEL},	    // CTRL-X is "*d
 #  else
-	{(char_u *)"\316\324 P", NORMAL},	    // SHIFT-Insert is P
+	{(char_u *)"\316\324 P", MODE_NORMAL},	    // SHIFT-Insert is P
 	{(char_u *)"\316\324 \"-dP", VIS_SEL},	    // SHIFT-Insert is "-dP
-	{(char_u *)"\316\324 \022\017\"", INSERT}, // SHIFT-Insert is ^R^O"
+	{(char_u *)"\316\324 \022\017\"", MODE_INSERT}, // SHIFT-Insert is ^R^O"
 	{(char_u *)"\316\325 y", VIS_SEL},	    // CTRL-Insert is y
 	{(char_u *)"\316\327 d", VIS_SEL},	    // SHIFT-Del is d
 	{(char_u *)"\316\330 d", VIS_SEL},	    // CTRL-Del is d
@@ -2733,9 +2738,9 @@ static struct initmap initmappings[] =
 {
 	// Use the Standard MacOS binding.
 	// paste, copy and cut
-	{(char_u *)"<D-v> \"*P", NORMAL},
+	{(char_u *)"<D-v> \"*P", MODE_NORMAL},
 	{(char_u *)"<D-v> \"-d\"*P", VIS_SEL},
-	{(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
+	{(char_u *)"<D-v> <C-R>*", MODE_INSERT | MODE_CMDLINE},
 	{(char_u *)"<D-c> \"*y", VIS_SEL},
 	{(char_u *)"<D-x> \"*d", VIS_SEL},
 	{(char_u *)"<Backspace> \"-d", VIS_SEL},
--- a/src/menu.c
+++ b/src/menu.c
@@ -1754,9 +1754,9 @@ get_menu_index(vimmenu_T *menu, int stat
 {
     int		idx;
 
-    if ((state & INSERT))
+    if ((state & MODE_INSERT))
 	idx = MENU_INDEX_INSERT;
-    else if (state & CMDLINE)
+    else if (state & MODE_CMDLINE)
 	idx = MENU_INDEX_CMDLINE;
 #ifdef FEAT_TERMINAL
     else if (term_use_loop())
@@ -1769,11 +1769,11 @@ get_menu_index(vimmenu_T *menu, int stat
 	else
 	    idx = MENU_INDEX_VISUAL;
     }
-    else if (state == HITRETURN || state == ASKMORE)
+    else if (state == MODE_HITRETURN || state == MODE_ASKMORE)
 	idx = MENU_INDEX_CMDLINE;
     else if (finish_op)
 	idx = MENU_INDEX_OP_PENDING;
-    else if ((state & NORMAL))
+    else if ((state & MODE_NORMAL))
 	idx = MENU_INDEX_NORMAL;
     else
 	idx = MENU_INDEX_INVALID;
@@ -1929,15 +1929,16 @@ get_menu_mode(void)
 	    return MENU_INDEX_SELECT;
 	return MENU_INDEX_VISUAL;
     }
-    if (State & INSERT)
+    if (State & MODE_INSERT)
 	return MENU_INDEX_INSERT;
-    if ((State & CMDLINE) || State == ASKMORE || State == HITRETURN)
+    if ((State & MODE_CMDLINE) || State == MODE_ASKMORE
+						    || State == MODE_HITRETURN)
 	return MENU_INDEX_CMDLINE;
     if (finish_op)
 	return MENU_INDEX_OP_PENDING;
-    if (State & NORMAL)
+    if (State & MODE_NORMAL)
 	return MENU_INDEX_NORMAL;
-    if (State & LANGMAP)	// must be a "r" command, like Insert mode
+    if (State & MODE_LANGMAP)	// must be a "r" command, like Insert mode
 	return MENU_INDEX_INSERT;
     return MENU_INDEX_INVALID;
 }
--- a/src/message.c
+++ b/src/message.c
@@ -1179,7 +1179,7 @@ wait_return(int redraw)
 	// just changed.
 	screenalloc(FALSE);
 
-	State = HITRETURN;
+	State = MODE_HITRETURN;
 	setmouse();
 #ifdef USE_ON_FLY_SCROLL
 	dont_scroll = TRUE;		// disallow scrolling here
@@ -1351,7 +1351,7 @@ wait_return(int redraw)
 				  (Rows - cmdline_row - 1) * Columns + sc_col)
 	VIM_CLEAR(keep_msg);	    // don't redisplay message, it's too long
 
-    if (tmpState == SETWSIZE)	    // got resize event while in vgetc()
+    if (tmpState == MODE_SETWSIZE)  // got resize event while in vgetc()
     {
 	starttermcap();		    // start termcap before redrawing
 	shell_resized();
@@ -1408,7 +1408,7 @@ set_keep_msg(char_u *s, int attr)
 set_keep_msg_from_hist(void)
 {
     if (keep_msg == NULL && last_msg_hist != NULL && msg_scrolled == 0
-							  && (State & NORMAL))
+						      && (State & MODE_NORMAL))
 	set_keep_msg(last_msg_hist->msg, last_msg_hist->attr);
 }
 #endif
@@ -2284,7 +2284,7 @@ msg_puts_display(
 	     */
 	    if (lines_left > 0)
 		--lines_left;
-	    if (p_more && lines_left == 0 && State != HITRETURN
+	    if (p_more && lines_left == 0 && State != MODE_HITRETURN
 					    && !msg_no_more && !exmode_active)
 	    {
 #ifdef FEAT_CON_DIALOG
@@ -2847,7 +2847,7 @@ do_more_prompt(int typed_char)
     // We get called recursively when a timer callback outputs a message. In
     // that case don't show another prompt. Also when at the hit-Enter prompt
     // and nothing was typed.
-    if (entered || (State == HITRETURN && typed_char == 0))
+    if (entered || (State == MODE_HITRETURN && typed_char == 0))
 	return FALSE;
     entered = TRUE;
 
@@ -2860,7 +2860,7 @@ do_more_prompt(int typed_char)
 	    mp_last = msg_sb_start(mp_last->sb_prev);
     }
 
-    State = ASKMORE;
+    State = MODE_ASKMORE;
     setmouse();
     if (typed_char == NUL)
 	msg_moremsg(FALSE);
@@ -2880,7 +2880,7 @@ do_more_prompt(int typed_char)
 #if defined(FEAT_MENU) && defined(FEAT_GUI)
 	if (c == K_MENU)
 	{
-	    int idx = get_menu_index(current_menu, ASKMORE);
+	    int idx = get_menu_index(current_menu, MODE_ASKMORE);
 
 	    // Used a menu.  If it starts with CTRL-Y, it must
 	    // be a "Copy" for the clipboard.  Otherwise
@@ -3329,29 +3329,29 @@ msg_moremsg(int full)
 }
 
 /*
- * Repeat the message for the current mode: ASKMORE, EXTERNCMD, CONFIRM or
- * exmode_active.
+ * Repeat the message for the current mode: MODE_ASKMORE, MODE_EXTERNCMD,
+ * MODE_CONFIRM or exmode_active.
  */
     void
 repeat_message(void)
 {
-    if (State == ASKMORE)
+    if (State == MODE_ASKMORE)
     {
 	msg_moremsg(TRUE);	// display --more-- message again
 	msg_row = Rows - 1;
     }
 #ifdef FEAT_CON_DIALOG
-    else if (State == CONFIRM)
+    else if (State == MODE_CONFIRM)
     {
 	display_confirm_msg();	// display ":confirm" message again
 	msg_row = Rows - 1;
     }
 #endif
-    else if (State == EXTERNCMD)
+    else if (State == MODE_EXTERNCMD)
     {
 	windgoto(msg_row, msg_col); // put cursor back
     }
-    else if (State == HITRETURN || State == SETWSIZE)
+    else if (State == MODE_HITRETURN || State == MODE_SETWSIZE)
     {
 	if (msg_row == Rows - 1)
 	{
@@ -3458,7 +3458,7 @@ msg_end(void)
      * we have to redraw the window.
      * Do not do this if we are abandoning the file or editing the command line.
      */
-    if (!exiting && need_wait_return && !(State & CMDLINE))
+    if (!exiting && need_wait_return && !(State & MODE_CMDLINE))
     {
 	wait_return(FALSE);
 	return FALSE;
@@ -3811,7 +3811,7 @@ do_dialog(
 #endif
 
     oldState = State;
-    State = CONFIRM;
+    State = MODE_CONFIRM;
     setmouse();
 
     // Ensure raw mode here.
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -455,13 +455,13 @@ plines_win_col(win_T *wp, linenr_T lnum,
 
     /*
      * If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
-     * INSERT mode, then col must be adjusted so that it represents the last
-     * screen position of the TAB.  This only fixes an error when the TAB wraps
-     * from one screen line to the next (when 'columns' is not a multiple of
-     * 'ts') -- webb.
+     * MODE_INSERT state, then col must be adjusted so that it represents the
+     * last screen position of the TAB.  This only fixes an error when the TAB
+     * wraps from one screen line to the next (when 'columns' is not a multiple
+     * of 'ts') -- webb.
      */
-    if (*s == TAB && (State & NORMAL) && (!wp->w_p_list ||
-							wp->w_lcs_chars.tab1))
+    if (*s == TAB && (State & MODE_NORMAL)
+				    && (!wp->w_p_list || wp->w_lcs_chars.tab1))
 	col += win_lbr_chartabsize(wp, line, s, (colnr_T)col, NULL) - 1;
 
     /*
@@ -595,7 +595,7 @@ ask_yesno(char_u *str, int direct)
 #ifdef USE_ON_FLY_SCROLL
     dont_scroll = TRUE;		// disallow scrolling here
 #endif
-    State = CONFIRM;		// mouse behaves like with :confirm
+    State = MODE_CONFIRM;	// mouse behaves like with :confirm
     setmouse();			// disables mouse for xterm
     ++no_mapping;
     ++allow_keys;		// no mapping here, but recognize keys
@@ -656,18 +656,19 @@ get_mode(char_u *buf)
 	        buf[i++] = 's';
 	}
     }
-    else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
-		|| State == CONFIRM)
+    else if (State == MODE_HITRETURN || State == MODE_ASKMORE
+						      || State == MODE_SETWSIZE
+		|| State == MODE_CONFIRM)
     {
 	buf[i++] = 'r';
-	if (State == ASKMORE)
+	if (State == MODE_ASKMORE)
 	    buf[i++] = 'm';
-	else if (State == CONFIRM)
+	else if (State == MODE_CONFIRM)
 	    buf[i++] = '?';
     }
-    else if (State == EXTERNCMD)
+    else if (State == MODE_EXTERNCMD)
 	buf[i++] = '!';
-    else if (State & INSERT)
+    else if (State & MODE_INSERT)
     {
 	if (State & VREPLACE_FLAG)
 	{
@@ -687,7 +688,7 @@ get_mode(char_u *buf)
 	else if (ctrl_x_mode_not_defined_yet())
 	    buf[i++] = 'x';
     }
-    else if ((State & CMDLINE) || exmode_active)
+    else if ((State & MODE_CMDLINE) || exmode_active)
     {
 	buf[i++] = 'c';
 	if (exmode_active == EXMODE_VIM)
@@ -861,8 +862,8 @@ get_keystroke(void)
 
 	if (n == KEYLEN_REMOVED)  // key code removed
 	{
-	    if (must_redraw != 0 && !need_wait_return
-				 && (State & (CMDLINE|HITRETURN|ASKMORE)) == 0)
+	    if (must_redraw != 0 && !need_wait_return && (State
+			& (MODE_CMDLINE | MODE_HITRETURN | MODE_ASKMORE)) == 0)
 	    {
 		// Redrawing was postponed, do it now.
 		update_screen(0);
@@ -1014,7 +1015,7 @@ prompt_for_number(int *mouse_used)
     save_cmdline_row = cmdline_row;
     cmdline_row = 0;
     save_State = State;
-    State = CMDLINE;
+    State = MODE_CMDLINE;
     // May show different mouse shape.
     setmouse();
 
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -30,8 +30,9 @@ virtual_active(void)
     if (virtual_op != MAYBE)
 	return virtual_op;
     return (cur_ve_flags == VE_ALL
-	    || ((cur_ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
-	    || ((cur_ve_flags & VE_INSERT) && (State & INSERT)));
+	    || ((cur_ve_flags & VE_BLOCK) && VIsual_active
+						      && VIsual_mode == Ctrl_V)
+	    || ((cur_ve_flags & VE_INSERT) && (State & MODE_INSERT)));
 }
 
 /*
@@ -136,7 +137,7 @@ coladvance2(
     int		head = 0;
 #endif
 
-    one_more = (State & INSERT)
+    one_more = (State & MODE_INSERT)
 		    || restart_edit != NUL
 		    || (VIsual_active && *p_sel != 'o')
 		    || ((get_ve_flags() & VE_ONEMORE) && wcol < MAXCOL);
@@ -169,7 +170,7 @@ coladvance2(
 		csize--;
 
 	    if (wcol / width > (colnr_T)csize / width
-		    && ((State & INSERT) == 0 || (int)wcol > csize + 1))
+		    && ((State & MODE_INSERT) == 0 || (int)wcol > csize + 1))
 	    {
 		// In case of line wrapping don't move the cursor beyond the
 		// right screen edge.  In Insert mode allow going just beyond
@@ -566,7 +567,7 @@ check_cursor_col_win(win_T *win)
 	// - in Insert mode or restarting Insert mode
 	// - in Visual mode and 'selection' isn't "old"
 	// - 'virtualedit' is set
-	if ((State & INSERT) || restart_edit
+	if ((State & MODE_INSERT) || restart_edit
 		|| (VIsual_active && *p_sel != 'o')
 		|| (cur_ve_flags & VE_ONEMORE)
 		|| virtual_active())
@@ -1836,22 +1837,23 @@ call_shell(char_u *cmd, int opt)
 }
 
 /*
- * VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
- * NORMAL State with a condition.  This function returns the real State.
+ * MODE_VISUAL, MODE_SELECT and MODE_OP_PENDING State are never set, they are
+ * equal to MODE_NORMAL State with a condition.  This function returns the real
+ * State.
  */
     int
 get_real_state(void)
 {
-    if (State & NORMAL)
+    if (State & MODE_NORMAL)
     {
 	if (VIsual_active)
 	{
 	    if (VIsual_select)
-		return SELECTMODE;
-	    return VISUAL;
+		return MODE_SELECT;
+	    return MODE_VISUAL;
 	}
 	else if (finish_op)
-	    return OP_PENDING;
+	    return MODE_OP_PENDING;
     }
     return State;
 }
@@ -2271,7 +2273,7 @@ parse_shape_opt(int what)
 get_shape_idx(int mouse)
 {
 #ifdef FEAT_MOUSESHAPE
-    if (mouse && (State == HITRETURN || State == ASKMORE))
+    if (mouse && (State == MODE_HITRETURN || State == MODE_ASKMORE))
     {
 # ifdef FEAT_GUI
 	int x, y;
@@ -2286,15 +2288,15 @@ get_shape_idx(int mouse)
     if (mouse && drag_sep_line)
 	return SHAPE_IDX_VDRAG;
 #endif
-    if (!mouse && State == SHOWMATCH)
+    if (!mouse && State == MODE_SHOWMATCH)
 	return SHAPE_IDX_SM;
     if (State & VREPLACE_FLAG)
 	return SHAPE_IDX_R;
     if (State & REPLACE_FLAG)
 	return SHAPE_IDX_R;
-    if (State & INSERT)
+    if (State & MODE_INSERT)
 	return SHAPE_IDX_I;
-    if (State & CMDLINE)
+    if (State & MODE_CMDLINE)
     {
 	if (cmdline_at_end())
 	    return SHAPE_IDX_C;
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -269,7 +269,7 @@ do_mouse(
 		if (!mouse_has(MOUSE_VISUAL))
 		    return FALSE;
 	    }
-	    else if (State == NORMAL && !mouse_has(MOUSE_NORMAL))
+	    else if (State == MODE_NORMAL && !mouse_has(MOUSE_NORMAL))
 		return FALSE;
 	}
 
@@ -355,7 +355,7 @@ do_mouse(
     // CTRL right mouse button does CTRL-T
     if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT)
     {
-	if (State & INSERT)
+	if (State & MODE_INSERT)
 	    stuffcharReadbuff(Ctrl_O);
 	if (count > 1)
 	    stuffnumReadbuff(count);
@@ -399,7 +399,7 @@ do_mouse(
     // Middle mouse button does a 'put' of the selected text
     if (which_button == MOUSE_MIDDLE)
     {
-	if (State == NORMAL)
+	if (State == MODE_NORMAL)
 	{
 	    // If an operator was pending, we don't know what the user wanted
 	    // to do. Go back to normal mode: Clear the operator and beep().
@@ -430,7 +430,7 @@ do_mouse(
 	    // The rest is below jump_to_mouse()
 	}
 
-	else if ((State & INSERT) == 0)
+	else if ((State & MODE_INSERT) == 0)
 	    return FALSE;
 
 	// Middle click in insert mode doesn't move the mouse, just insert the
@@ -438,7 +438,7 @@ do_mouse(
 	// with do_put().
 	// Also paste at the cursor if the current mode isn't in 'mouse' (only
 	// happens for the GUI).
-	if ((State & INSERT) || !mouse_has(MOUSE_NORMAL))
+	if ((State & MODE_INSERT) || !mouse_has(MOUSE_NORMAL))
 	{
 	    if (regname == '.')
 		insert_reg(regname, TRUE);
@@ -645,7 +645,7 @@ do_mouse(
 	}
     }
 
-    if ((State & (NORMAL | INSERT))
+    if ((State & (MODE_NORMAL | MODE_INSERT))
 			    && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
     {
 	if (which_button == MOUSE_LEFT)
@@ -838,7 +838,7 @@ do_mouse(
 	}
     }
     // If Visual mode started in insert mode, execute "CTRL-O"
-    else if ((State & INSERT) && VIsual_active)
+    else if ((State & MODE_INSERT) && VIsual_active)
 	stuffcharReadbuff(Ctrl_O);
 
     // Middle mouse click: Put text before cursor.
@@ -895,7 +895,7 @@ do_mouse(
     else if ((mod_mask & MOD_MASK_CTRL) || (curbuf->b_help
 		     && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK))
     {
-	if (State & INSERT)
+	if (State & MODE_INSERT)
 	    stuffcharReadbuff(Ctrl_O);
 	stuffcharReadbuff(Ctrl_RSB);
 	got_click = FALSE;		// ignore drag&release now
@@ -905,7 +905,7 @@ do_mouse(
     // the mouse pointer
     else if ((mod_mask & MOD_MASK_SHIFT))
     {
-	if ((State & INSERT) || (VIsual_active && VIsual_select))
+	if ((State & MODE_INSERT) || (VIsual_active && VIsual_select))
 	    stuffcharReadbuff(Ctrl_O);
 	if (which_button == MOUSE_LEFT)
 	    stuffcharReadbuff('*');
@@ -934,7 +934,8 @@ do_mouse(
 	}
 #endif
     }
-    else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))
+    else if ((mod_mask & MOD_MASK_MULTI_CLICK)
+				       && (State & (MODE_NORMAL | MODE_INSERT))
 	     && mouse_has(MOUSE_VISUAL))
     {
 	if (is_click || !VIsual_active)
@@ -1441,13 +1442,14 @@ setmouse(void)
 
     if (VIsual_active)
 	checkfor = MOUSE_VISUAL;
-    else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
+    else if (State == MODE_HITRETURN || State == MODE_ASKMORE
+						     || State == MODE_SETWSIZE)
 	checkfor = MOUSE_RETURN;
-    else if (State & INSERT)
+    else if (State & MODE_INSERT)
 	checkfor = MOUSE_INSERT;
-    else if (State & CMDLINE)
+    else if (State & MODE_CMDLINE)
 	checkfor = MOUSE_COMMAND;
-    else if (State == CONFIRM || State == EXTERNCMD)
+    else if (State == MODE_CONFIRM || State == MODE_EXTERNCMD)
 	checkfor = ' '; // don't use mouse for ":confirm" or ":!cmd"
     else
 	checkfor = MOUSE_NORMAL;    // assume normal mode
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -1843,7 +1843,7 @@ nb_do_cmd(
 	    out_flush_cursor(TRUE, FALSE);
 
 	    // Quit a hit-return or more prompt.
-	    if (State == HITRETURN || State == ASKMORE)
+	    if (State == MODE_HITRETURN || State == MODE_ASKMORE)
 	    {
 #ifdef FEAT_GUI_GTK
 		if (gui.in_use && gtk_main_level() > 0)
@@ -2229,7 +2229,7 @@ nb_do_cmd(
 	out_flush_cursor(TRUE, FALSE);
 
 	// Quit a hit-return or more prompt.
-	if (State == HITRETURN || State == ASKMORE)
+	if (State == MODE_HITRETURN || State == MODE_ASKMORE)
 	{
 #ifdef FEAT_GUI_GTK
 	    if (gui.in_use && gtk_main_level() > 0)
@@ -2323,7 +2323,7 @@ special_keys(char_u *args)
 	    strcpy(&keybuf[i], tok);
 	    vim_snprintf(cmdbuf, sizeof(cmdbuf),
 				 "<silent><%s> :nbkey %s<CR>", keybuf, keybuf);
-	    do_map(0, (char_u *)cmdbuf, NORMAL, FALSE);
+	    do_map(0, (char_u *)cmdbuf, MODE_NORMAL, FALSE);
 	}
 	tok = strtok(NULL, " ");
     }
--- a/src/normal.c
+++ b/src/normal.c
@@ -391,7 +391,7 @@ normal_cmd_get_more_chars(
     {
 	if (repl)
 	{
-	    State = REPLACE;	// pretend Replace mode
+	    State = MODE_REPLACE;	// pretend Replace mode
 #ifdef CURSOR_SHAPE
 	    ui_cursor_shape();	// show different cursor shape
 #endif
@@ -402,9 +402,9 @@ normal_cmd_get_more_chars(
 	    --no_mapping;
 	    --allow_keys;
 	    if (repl)
-		State = LREPLACE;
+		State = MODE_LREPLACE;
 	    else
-		State = LANGMAP;
+		State = MODE_LANGMAP;
 	    langmap_active = TRUE;
 	}
 #ifdef HAVE_INPUT_METHOD
@@ -413,7 +413,7 @@ normal_cmd_get_more_chars(
 	if (lang && curbuf->b_p_iminsert == B_IMODE_IM)
 	    im_set_active(TRUE);
 #endif
-	if ((State & INSERT) && !p_ek)
+	if ((State & MODE_INSERT) && !p_ek)
 	{
 #ifdef FEAT_JOB_CHANNEL
 	    ch_log_output = TRUE;
@@ -426,7 +426,7 @@ normal_cmd_get_more_chars(
 
 	*cp = plain_vgetc();
 
-	if ((State & INSERT) && !p_ek)
+	if ((State & MODE_INSERT) && !p_ek)
 	{
 #ifdef FEAT_JOB_CHANNEL
 	    ch_log_output = TRUE;
@@ -441,7 +441,7 @@ normal_cmd_get_more_chars(
 	    // Undo the decrement done above
 	    ++no_mapping;
 	    ++allow_keys;
-	    State = NORMAL_BUSY;
+	    State = MODE_NORMAL_BUSY;
 	}
 #ifdef HAVE_INPUT_METHOD
 	if (lang)
@@ -452,7 +452,7 @@ normal_cmd_get_more_chars(
 	}
 	p_smd = save_smd;
 #endif
-	State = NORMAL_BUSY;
+	State = MODE_NORMAL_BUSY;
 #ifdef FEAT_CMDL_INFO
 	*need_flushbuf |= add_to_showcmd(*cp);
 #endif
@@ -606,7 +606,7 @@ normal_cmd_wait_for_msg(void)
 
     // Draw the cursor with the right shape here
     if (restart_edit != 0)
-	State = INSERT;
+	State = MODE_INSERT;
 
     // If need to redraw, and there is a "keep_msg", redraw before the
     // delay
@@ -714,7 +714,7 @@ normal_cmd(
 
     mapped_len = typebuf_maplen();
 
-    State = NORMAL_BUSY;
+    State = MODE_NORMAL_BUSY;
 #ifdef USE_ON_FLY_SCROLL
     dont_scroll = FALSE;	// allow scrolling here
 #endif
@@ -731,7 +731,7 @@ normal_cmd(
      * Get the command character from the user.
      */
     c = safe_vgetc();
-    LANGMAP_ADJUST(c, get_real_state() != SELECTMODE);
+    LANGMAP_ADJUST(c, get_real_state() != MODE_SELECT);
 
     // If a mapping was started in Visual or Select mode, remember the length
     // of the mapping.  This is used below to not return to Insert mode for as
@@ -888,7 +888,7 @@ normal_cmd(
 	    did_cursorhold = FALSE;
     }
 
-    State = NORMAL;
+    State = MODE_NORMAL;
 
     if (ca.nchar == ESC)
     {
@@ -4873,7 +4873,7 @@ nv_replace(cmdarg_T *cap)
 	    // composing characters for utf-8.
 	    for (n = cap->count1; n > 0; --n)
 	    {
-		State = REPLACE;
+		State = MODE_REPLACE;
 		if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y)
 		{
 		    int c = ins_copychar(curwin->w_cursor.lnum
@@ -6831,7 +6831,7 @@ set_cursor_for_append_to_line(void)
 
 	// Pretend Insert mode here to allow the cursor on the
 	// character past the end of the line
-	State = INSERT;
+	State = MODE_INSERT;
 	coladvance((colnr_T)MAXCOL);
 	State = save_State;
     }
@@ -6983,7 +6983,7 @@ nv_edit(cmdarg_T *cap)
 
 	    // Pretend Insert mode here to allow the cursor on the
 	    // character past the end of the line
-	    State = INSERT;
+	    State = MODE_INSERT;
 	    coladvance(getviscol());
 	    State = save_State;
 	}
--- a/src/ops.c
+++ b/src/ops.c
@@ -294,7 +294,7 @@ shift_block(oparg_T *oap, int amount)
     p_ri = 0;			// don't want revins in indent
 #endif
 
-    State = INSERT;		// don't want REPLACE for State
+    State = MODE_INSERT;	// don't want MODE_REPLACE for State
     block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
     if (bd.is_short)
 	return;
@@ -488,7 +488,7 @@ block_insert(
     linenr_T	lnum;		// loop var
     int		oldstate = State;
 
-    State = INSERT;		// don't want REPLACE for State
+    State = MODE_INSERT;	// don't want MODE_REPLACE for State
     s_len = (unsigned)STRLEN(s);
 
     for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++)
@@ -991,7 +991,7 @@ replace_character(int c)
 {
     int n = State;
 
-    State = REPLACE;
+    State = MODE_REPLACE;
     ins_char(c);
     State = n;
     // Backup to the replaced character.
@@ -1842,7 +1842,7 @@ adjust_cursor_eol(void)
     if (curwin->w_cursor.col > 0
 	    && gchar_cursor() == NUL
 	    && (cur_ve_flags & VE_ONEMORE) == 0
-	    && !(restart_edit || (State & INSERT)))
+	    && !(restart_edit || (State & MODE_INSERT)))
     {
 	// Put the cursor on the last character in the line.
 	dec_cursor();
--- a/src/option.c
+++ b/src/option.c
@@ -2915,7 +2915,7 @@ set_bool_option(
     {
 	if (p_im)
 	{
-	    if ((State & INSERT) == 0)
+	    if ((State & MODE_INSERT) == 0)
 		need_start_insertmode = TRUE;
 	    stop_insert_mode = FALSE;
 	}
@@ -3110,7 +3110,7 @@ set_bool_option(
 	// Only de-activate it here, it will be enabled when changing mode.
 	if (p_imdisable)
 	    im_set_active(FALSE);
-	else if (State & INSERT)
+	else if (State & MODE_INSERT)
 	    // When the option is set from an autocommand, it may need to take
 	    // effect right away.
 	    im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4976,7 +4976,7 @@ mch_call_shell_fork(
 		p_more_save = p_more;
 		p_more = FALSE;
 		old_State = State;
-		State = EXTERNCMD;	// don't redraw at window resize
+		State = MODE_EXTERNCMD;	// don't redraw at window resize
 
 		if ((options & SHELL_WRITE) && toshell_fd >= 0)
 		{
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1678,7 +1678,7 @@ WaitForChar(long msec, int ignore_input)
 # ifdef FEAT_MBYTE_IME
 	// May have to redraw if the cursor ends up in the wrong place.
 	// Only when not peeking.
-	if (State & CMDLINE && msg_row == Rows - 1 && msec != 0)
+	if (State == MODE_CMDLINE && msg_row == Rows - 1 && msec != 0)
 	{
 	    CONSOLE_SCREEN_BUFFER_INFO csbi;
 
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -101,7 +101,7 @@ pum_display(
     win_T	*pvwin;
 #endif
 #ifdef FEAT_RIGHTLEFT
-    int		right_left = State == CMDLINE ? FALSE : curwin->w_p_rl;
+    int		right_left = State == MODE_CMDLINE ? FALSE : curwin->w_p_rl;
 #endif
 
     do
@@ -119,7 +119,7 @@ pum_display(
 	// Remember the essential parts of the window position and size, so we
 	// can decide when to reposition the popup menu.
 	pum_window = curwin;
-	if (State == CMDLINE)
+	if (State == MODE_CMDLINE)
 	    // cmdline completion popup menu
 	    pum_win_row = cmdline_row;
 	else
@@ -159,7 +159,7 @@ pum_display(
 	{
 	    // pum above "pum_win_row"
 
-	    if (State == CMDLINE)
+	    if (State == MODE_CMDLINE)
 		// for cmdline pum, no need for context lines
 		context_lines = 0;
 	    else
@@ -191,7 +191,7 @@ pum_display(
 	{
 	    // pum below "pum_win_row"
 
-	    if (State == CMDLINE)
+	    if (State == MODE_CMDLINE)
 		// for cmdline pum, no need for context lines
 		context_lines = 0;
 	    else
@@ -235,7 +235,7 @@ pum_display(
 
 	// Calculate column
 #ifdef FEAT_WILDMENU
-	if (State == CMDLINE)
+	if (State == MODE_CMDLINE)
 	    // cmdline completion popup menu
 	    cursor_col = cmdline_compl_startcol();
 	else
--- a/src/screen.c
+++ b/src/screen.c
@@ -68,13 +68,13 @@ conceal_cursor_line(win_T *wp)
 
     if (*wp->w_p_cocu == NUL)
 	return FALSE;
-    if (get_real_state() & VISUAL)
+    if (get_real_state() & MODE_VISUAL)
 	c = 'v';
-    else if (State & INSERT)
+    else if (State & MODE_INSERT)
 	c = 'i';
-    else if (State & NORMAL)
+    else if (State & MODE_NORMAL)
 	c = 'n';
-    else if (State & CMDLINE)
+    else if (State & MODE_CMDLINE)
 	c = 'c';
     else
 	return FALSE;
@@ -4164,7 +4164,7 @@ showmode(void)
     int		sub_attr;
 
     do_mode = ((p_smd && msg_silent == 0)
-	    && ((State & INSERT)
+	    && ((State & MODE_INSERT)
 		|| restart_edit != NUL
 		|| VIsual_active));
     if (do_mode || reg_recording != 0)
@@ -4238,7 +4238,7 @@ showmode(void)
 		    msg_puts_attr(_(" VREPLACE"), attr);
 		else if (State & REPLACE_FLAG)
 		    msg_puts_attr(_(" REPLACE"), attr);
-		else if (State & INSERT)
+		else if (State & MODE_INSERT)
 		{
 #ifdef FEAT_RIGHTLEFT
 		    if (p_ri)
@@ -4258,7 +4258,7 @@ showmode(void)
 		    msg_puts_attr(_(" Hebrew"), attr);
 #endif
 #ifdef FEAT_KEYMAP
-		if (State & LANGMAP)
+		if (State & MODE_LANGMAP)
 		{
 # ifdef FEAT_ARABIC
 		    if (curwin->w_p_arab)
@@ -4270,7 +4270,7 @@ showmode(void)
 			    msg_puts_attr((char *)NameBuff, attr);
 		}
 #endif
-		if ((State & INSERT) && p_paste)
+		if ((State & MODE_INSERT) && p_paste)
 		    msg_puts_attr(_(" (paste)"), attr);
 
 		if (VIsual_active)
--- a/src/search.c
+++ b/src/search.c
@@ -2860,7 +2860,7 @@ showmatch(
 	    save_dollar_vcol = dollar_vcol;
 #ifdef CURSOR_SHAPE
 	    save_state = State;
-	    State = SHOWMATCH;
+	    State = MODE_SHOWMATCH;
 	    ui_cursor_shape();		// may show different cursor shape
 #endif
 	    curwin->w_cursor = mpos;	// move to matching char
--- a/src/tag.c
+++ b/src/tag.c
@@ -2642,7 +2642,7 @@ findtags_add_match(
 		vim_strncpy(mfp, tagpp->tagname, len);
 
 	    // if wanted, re-read line to get long form too
-	    if (State & INSERT)
+	    if (State & MODE_INSERT)
 		st->get_searchpat = p_sft;
 	}
     }
--- a/src/term.c
+++ b/src/term.c
@@ -2180,7 +2180,6 @@ set_termname(char_u *term)
 #if defined(EXITFREE) || defined(PROTO)
 
 # ifdef HAVE_DEL_CURTERM
-#  undef TERMINAL	    // name clash in term.h
 #  include <term.h>	    // declares cur_term
 # endif
 
@@ -3468,10 +3467,10 @@ set_shellsize(int width, int height, int
     if (width < 0 || height < 0)    // just checking...
 	return;
 
-    if (State == HITRETURN || State == SETWSIZE)
+    if (State == MODE_HITRETURN || State == MODE_SETWSIZE)
     {
 	// postpone the resizing
-	State = SETWSIZE;
+	State = MODE_SETWSIZE;
 	return;
     }
 
@@ -3507,7 +3506,8 @@ set_shellsize(int width, int height, int
     // screenalloc() (also invoked from screenclear()).  That is because the
     // "busy" check above may skip this, but not screenalloc().
 
-    if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
+    if (State != MODE_ASKMORE && State != MODE_EXTERNCMD
+						      && State != MODE_CONFIRM)
 	screenclear();
     else
 	screen_start();	    // don't know where cursor is now
@@ -3529,8 +3529,8 @@ set_shellsize(int width, int height, int
 	 * Always need to call update_screen() or screenalloc(), to make
 	 * sure Rows/Columns and the size of ScreenLines[] is correct!
 	 */
-	if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
-							     || exmode_active)
+	if (State == MODE_ASKMORE || State == MODE_EXTERNCMD
+				     || State == MODE_CONFIRM || exmode_active)
 	{
 	    screenalloc(FALSE);
 	    repeat_message();
@@ -3539,7 +3539,7 @@ set_shellsize(int width, int height, int
 	{
 	    if (curwin->w_p_scb)
 		do_check_scrollbind(TRUE);
-	    if (State & CMDLINE)
+	    if (State & MODE_CMDLINE)
 	    {
 		update_screen(NOT_VALID);
 		redrawcmdline();
@@ -4056,9 +4056,9 @@ term_cursor_mode(int forced)
 	return;
     }
 
-    if ((State & REPLACE) == REPLACE)
+    if ((State & MODE_REPLACE) == MODE_REPLACE)
     {
-	if (forced || showing_mode != REPLACE)
+	if (forced || showing_mode != MODE_REPLACE)
 	{
 	    if (*T_CSR != NUL)
 		p = T_CSR;	// Replace mode cursor
@@ -4067,22 +4067,22 @@ term_cursor_mode(int forced)
 	    if (*p != NUL)
 	    {
 		out_str(p);
-		showing_mode = REPLACE;
+		showing_mode = MODE_REPLACE;
 	    }
 	}
     }
-    else if (State & INSERT)
+    else if (State & MODE_INSERT)
     {
-	if ((forced || showing_mode != INSERT) && *T_CSI != NUL)
+	if ((forced || showing_mode != MODE_INSERT) && *T_CSI != NUL)
 	{
 	    out_str(T_CSI);	    // Insert mode cursor
-	    showing_mode = INSERT;
+	    showing_mode = MODE_INSERT;
 	}
     }
-    else if (forced || showing_mode != NORMAL)
+    else if (forced || showing_mode != MODE_NORMAL)
     {
 	out_str(T_CEI);		    // non-Insert mode cursor
-	showing_mode = NORMAL;
+	showing_mode = MODE_NORMAL;
     }
 }
 
@@ -5400,7 +5400,7 @@ check_termcode(
 	 * Skip this position if p_ek is not set and tp[0] is an ESC and we
 	 * are in Insert mode.
 	 */
-	if (*tp == ESC && !p_ek && (State & INSERT))
+	if (*tp == ESC && !p_ek && (State & MODE_INSERT))
 	    continue;
 
 	key_name[0] = NUL;	// no key name found yet
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1267,7 +1267,7 @@ write_to_term(buf_T *buffer, char_u *msg
 	// cleared.
 	// TODO: only update once in a while.
 	ch_log(term->tl_job->jv_channel, "updating screen");
-	if (buffer == curbuf && (State & CMDLINE) == 0)
+	if (buffer == curbuf && (State & MODE_CMDLINE) == 0)
 	{
 	    update_screen(VALID_NO_UPDATE);
 	    // update_screen() can be slow, check the terminal wasn't closed
@@ -2129,7 +2129,7 @@ term_vgetc()
     int modify_other_keys = curbuf->b_term->tl_vterm == NULL ? FALSE
 			: vterm_is_modify_other_keys(curbuf->b_term->tl_vterm);
 
-    State = TERMINAL;
+    State = MODE_TERMINAL;
     got_int = FALSE;
 #ifdef MSWIN
     ctrl_break_was_pressed = FALSE;
@@ -2508,7 +2508,7 @@ term_win_entered()
 	if (term_use_loop_check(TRUE))
 	{
 	    reset_VIsual_and_resel();
-	    if (State & INSERT)
+	    if (State & MODE_INSERT)
 		stop_insert_mode = TRUE;
 	}
 	mouse_was_outside = FALSE;
--- a/src/textformat.c
+++ b/src/textformat.c
@@ -330,7 +330,7 @@ internal_format(
 	undisplay_dollar();
 
 	// Offset between cursor position and line break is used by replace
-	// stack functions.  VREPLACE does not use this, and backspaces
+	// stack functions.  MODE_VREPLACE does not use this, and backspaces
 	// over the text instead.
 	if (State & VREPLACE_FLAG)
 	    orig_col = startcol;	// Will start backspacing from here
@@ -349,7 +349,7 @@ internal_format(
 
 	if (State & VREPLACE_FLAG)
 	{
-	    // In VREPLACE mode, we will backspace over the text to be
+	    // In MODE_VREPLACE state, we will backspace over the text to be
 	    // wrapped, so save a copy now to put on the next line.
 	    saved_text = vim_strsave(ml_get_cursor());
 	    curwin->w_cursor.col = orig_col;
@@ -428,7 +428,7 @@ internal_format(
 
 	if (State & VREPLACE_FLAG)
 	{
-	    // In VREPLACE mode we have backspaced over the text to be
+	    // In MODE_VREPLACE state we have backspaced over the text to be
 	    // moved, now we re-insert it into the new line.
 	    ins_bytes(saved_text);
 	    vim_free(saved_text);
@@ -1143,13 +1143,13 @@ format_lines(
 		}
 
 		// put cursor on last non-space
-		State = NORMAL;	// don't go past end-of-line
+		State = MODE_NORMAL;	// don't go past end-of-line
 		coladvance((colnr_T)MAXCOL);
 		while (curwin->w_cursor.col && vim_isspace(gchar_cursor()))
 		    dec_cursor();
 
 		// do the formatting, without 'showmode'
-		State = INSERT;	// for open_line()
+		State = MODE_INSERT;	// for open_line()
 		smd_save = p_smd;
 		p_smd = FALSE;
 		insertchar(NUL, INSCHAR_FORMAT
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4911,
+/**/
     4910,
 /**/
     4909,
--- a/src/vim.h
+++ b/src/vim.h
@@ -667,44 +667,46 @@ extern int (*dyn_libintl_wputenv)(const 
 #define MSG_HIST		0x1000
 
 /*
- * values for State
+ * Values for State.
  *
- * The lower bits up to 0x20 are used to distinguish normal/visual/op_pending
- * and cmdline/insert+replace mode.  This is used for mapping.  If none of
- * these bits are set, no mapping is done.
- * The upper bits are used to distinguish between other states.
+ * The lower bits up to 0x80 are used to distinguish normal/visual/op_pending
+ * /cmdline/insert/replace/terminal mode.  This is used for mapping.  If none
+ * of these bits are set, no mapping is done.  See the comment above do_map().
+ * The upper bits are used to distinguish between other states and variants of
+ * the base modes.
  */
-#define NORMAL		0x01	// Normal mode, command expected
-#define VISUAL		0x02	// Visual mode - use get_real_state()
-#define OP_PENDING	0x04	// Normal mode, operator is pending - use
+#define MODE_NORMAL	0x01	// Normal mode, command expected
+#define MODE_VISUAL	0x02	// Visual mode - use get_real_state()
+#define MODE_OP_PENDING	0x04	// Normal mode, operator is pending - use
 				// get_real_state()
-#define CMDLINE		0x08	// Editing command line
-#define INSERT		0x10	// Insert mode
-#define LANGMAP		0x20	// Language mapping, can be combined with
-				// INSERT and CMDLINE
+#define MODE_CMDLINE	0x08	// Editing the command line
+#define MODE_INSERT	0x10	// Insert mode, also for Replace mode
+#define MODE_LANGMAP	0x20	// Language mapping, can be combined with
+				// MODE_INSERT and MODE_CMDLINE
+#define MODE_SELECT	0x40	// Select mode, use get_real_state()
+#define MODE_TERMINAL	0x80	// Terminal mode
 
-#define REPLACE_FLAG	0x40	// Replace mode flag
-#define REPLACE		(REPLACE_FLAG + INSERT)
-#define VREPLACE_FLAG	0x80	// Virtual-replace mode flag
-#define VREPLACE	(REPLACE_FLAG + VREPLACE_FLAG + INSERT)
-#define LREPLACE	(REPLACE_FLAG + LANGMAP)
+#define MAP_ALL_MODES	0xff    // all mode bits used for mapping
+
+#define REPLACE_FLAG	0x100	// Replace mode flag
+#define MODE_REPLACE	(REPLACE_FLAG | MODE_INSERT)
+#define VREPLACE_FLAG	0x200	// Virtual-replace mode flag
+#define MODE_VREPLACE	(REPLACE_FLAG | VREPLACE_FLAG | MODE_INSERT)
+#define MODE_LREPLACE	(REPLACE_FLAG | MODE_LANGMAP)
 
-#define NORMAL_BUSY	(0x100 + NORMAL) // Normal mode, busy with a command
-#define HITRETURN	(0x200 + NORMAL) // waiting for return or command
-#define ASKMORE		0x300	// Asking if you want --more--
-#define SETWSIZE	0x400	// window size has changed
-#define ABBREV		0x500	// abbreviation instead of mapping
-#define EXTERNCMD	0x600	// executing an external command
-#define SHOWMATCH	(0x700 + INSERT) // show matching paren
-#define CONFIRM		0x800	// ":confirm" prompt
-#define SELECTMODE	0x1000	// Select mode, only for mappings
-#define TERMINAL        0x2000  // Terminal mode
+#define MODE_NORMAL_BUSY (0x1000 | MODE_NORMAL)
+				// Normal mode, busy with a command
+#define MODE_HITRETURN	(0x2000 | MODE_NORMAL)
+				// waiting for return or command
+#define MODE_ASKMORE	0x3000	// Asking if you want --more--
+#define MODE_SETWSIZE	0x4000	// window size has changed
+#define MODE_EXTERNCMD	0x5000	// executing an external command
+#define MODE_SHOWMATCH	(0x6000 | MODE_INSERT) // show matching paren
+#define MODE_CONFIRM	0x7000	// ":confirm" prompt
 #define MODE_ALL	0xffff
 
-#define MODE_MAX_LENGTH	4	// max mode length returned in mode()
-
-// all mode bits used for mapping
-#define MAP_ALL_MODES	(0x3f | SELECTMODE | TERMINAL)
+#define MODE_MAX_LENGTH	4	// max mode length used by get_mode(),
+				// including the terminating NUL
 
 // directions
 #define FORWARD			1
@@ -2484,7 +2486,6 @@ typedef enum {
   /*
    * Avoid clashes between Perl and Vim namespace.
    */
-# undef NORMAL
 # undef STRLEN
 # undef FF
 # undef OP_DELETE
--- a/src/window.c
+++ b/src/window.c
@@ -2259,7 +2259,7 @@ leaving_window(win_T *win)
     // When leaving the window (or closing the window) was done from a
     // callback we need to break out of the Insert mode loop and restart Insert
     // mode when entering the window again.
-    if (State & INSERT)
+    if (State & MODE_INSERT)
     {
 	stop_insert_mode = TRUE;
 	if (win->w_buffer->b_prompt_insert == NUL)
@@ -2281,7 +2281,7 @@ entering_window(win_T *win)
 
     // When entering the prompt window restart Insert mode if we were in Insert
     // mode when we left it and not already in Insert mode.
-    if ((State & INSERT) == 0)
+    if ((State & MODE_INSERT) == 0)
 	restart_edit = win->w_buffer->b_prompt_insert;
 }
 #endif