diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 3beb2b0..b26d73e 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -4540,6 +4540,21 @@ A jump table for the options with a short description can be found at |Q_op|.
 	When you set this option and Vim is unable to change the physical
 	number of lines of the display, the display may be messed up.
 
+						*'linenumber'* *'lnr'*
+'linenumber' 'lnr'	string	(default "none")
+			local to window
+			{not in Vi}
+	Controls how line numbers are shown:
+	value		effect	~
+	none		No line numbers are shown
+	number		Same as ":set number"
+	relative	Same as ":set relativenumber"
+	numrel		Same as ":set relativenumber", but instead of
+			showing '0' for the current line, show the actual
+			line number instead. The actual line number is
+			left-aligned to differentiate it from the relative
+			line number.
+
 						*'linespace'* *'lsp'*
 'linespace' 'lsp'	number	(default 0, 1 for Win32 GUI)
 			global
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index dd36112..330fb60 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -363,6 +363,9 @@ call <SID>BinOptionL("nu")
 call append("$", "relativenumber\tshow the relative line number for each line")
 call append("$", "\t(local to window)")
 call <SID>BinOptionL("rnu")
+call append("$", "linenumber\tshow the actual, relative, or a combination of both for each line")
+call append("$", "\t(local to window)")
+call <SID>OptionL("lnr")
 if has("linebreak")
   call append("$", "numberwidth\tnumber of columns to use for the line number")
   call append("$", "\t(local to window)")
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index 391e650..dbe6446 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -30,7 +30,7 @@ syn match   vimCommand contained	"\<z[-+^.=]\="
 " vimOptions are caught only when contained in a vimSet {{{2
 syn keyword vimOption contained	acd ambiwidth arabicshape autowriteall backupdir bdlay binary breakat bufhidden cd ci cinw co commentstring confirm cpoptions cscoperelative csre cursorcolumn delcombine diffopt ea efm ep et fdc fdo ffs fk foldcolumn foldmethod formatoptions gd go guifont guitabtooltip hid hkp iconstring imd include inex isi js kp linebreak lm lz matchpairs maxmemtot mkspellmem mod mousef mouset nf oft pa path pheader previewheight printmbcharset pvw remap rl ruf sc scrollopt selectmode shellpipe shiftround showfulltag sidescrolloff smarttab sp spf srr startofline suffixes switchbuf tabline tags tbs textmode timeout tl tpm ttimeoutlen ttymouse udf undoreload vbs vi vop wcm whichwrap wildignore winaltkeys winminwidth wmnu write
 syn keyword vimOption contained	ai ambw ari aw backupext beval biosk brk buflisted cdpath cin cinwords cocu compatible consk cpt cscopetag cst cursorline dex digraph ead ei equalalways eventignore fde fdt fileencoding fkmap foldenable foldminlines formatprg gdefault gp guifontset helpfile hidden hl ignorecase imdisable includeexpr inf isident key langmap lines lmap ma matchtime mco ml modeline mousefocus mousetime nrformats ofu para pdev pi previewwindow printmbfont qe report rlc ruler scb scs sessionoptions shellquote shiftwidth showmatch siso smc spc spl ss statusline suffixesadd sws tabpagemax tagstack tenc textwidth timeoutlen tm tr ttm ttyscroll udir updatecount vdir viewdir wa wd wi wildignorecase window winwidth wmw writeany
-syn keyword vimOption contained	akm anti arshape awa backupskip bex bioskey browsedir buftype cedit cindent clipboard cole complete conskey crb cscopetagorder csto cwh dg dip eadirection ek equalprg ex fdi fen fileencodings flp foldexpr foldnestmax fp gfm grepformat guifontwide helpheight highlight hlg im imi incsearch infercase isk keymap langmenu linespace loadplugins macatsui maxcombine mef mls modelines mousehide mp nu omnifunc paragraphs penc pm printdevice printoptions quoteescape restorescreen rnu rulerformat scr sect sft shellredir shm showmode sj smd spell splitbelow ssl stl sw sxq tabstop tal term tf title to ts tty ttytype ul updatetime ve viewoptions wak weirdinvert wic wildmenu winfixheight wiv wop writebackup
+syn keyword vimOption contained	akm anti arshape awa backupskip bex bioskey browsedir buftype cedit cindent clipboard cole complete conskey crb cscopetagorder csto cwh dg dip eadirection ek equalprg ex fdi fen fileencodings flp foldexpr foldnestmax fp gfm grepformat guifontwide helpheight highlight hlg im imi incsearch infercase isk keymap langmenu linenumber linespace lnr loadplugins macatsui maxcombine mef mls modelines mousehide mp nu omnifunc paragraphs penc pm printdevice printoptions quoteescape restorescreen rnu rulerformat scr sect sft shellredir shm showmode sj smd spell splitbelow ssl stl sw sxq tabstop tal term tf title to ts tty ttytype ul updatetime ve viewoptions wak weirdinvert wic wildmenu winfixheight wiv wop writebackup
 syn keyword vimOption contained	al antialias autochdir background balloondelay bexpr bk bs casemap cf cink cmdheight colorcolumn completefunc copyindent cryptmethod cscopeverbose csverb debug dict dir eb enc errorbells expandtab fdl fenc fileformat fml foldignore foldopen fs gfn grepprg guiheadroom helplang history hls imactivatekey iminsert inde insertmode iskeyword keymodel laststatus lisp lpl magic maxfuncdepth menuitems mm modifiable mousem mps number opendevice paste pex pmbcs printencoding prompt rdt revins ro runtimepath scroll sections sh shellslash shortmess showtabline slm sn spellcapcheck splitright ssop stmp swapfile syn tag tb termbidi tgst titlelen toolbar tsl ttybuiltin tw undodir ur verbose viminfo warn wfh wig wildmode winfixwidth wiw wrap writedelay
 syn keyword vimOption contained	aleph ar autoindent backspace ballooneval bg bkc bsdir cb cfu cinkeys cmdwinheight columns completeopt cot cscopepathcomp cspc cuc deco dictionary directory ed encoding errorfile exrc fdls fencs fileformats fmr foldlevel foldtext fsync gfs gtl guioptions hf hk hlsearch imak ims indentexpr is isp keywordprg lazyredraw lispwords ls makeef maxmapdepth mfd mmd modified mousemodel msm numberwidth operatorfunc pastetoggle pexpr pmbfn printexpr pt readonly ri rs sb scrollbind secure shcf shelltemp shortname shq sm so spellfile spr st sts swapsync synmaxcol tagbsearch tbi termencoding thesaurus titleold toolbariconsize tsr ttyfast tx undofile ut verbosefile virtualedit wb wfw wildchar wildoptions winheight wm wrapmargin ws
 syn keyword vimOption contained	allowrevins arab autoread backup balloonexpr bh bl bsk cc ch cino cmp com concealcursor cp cscopeprg csprg cul def diff display edcompatible endofline errorformat fcl fdm fex filetype fo foldlevelstart formatexpr ft gfw gtt guipty hh hkmap ic imc imsearch indentkeys isf isprint km lbr list lsp makeprg maxmem mh mmp more mouses mzq nuw opfunc patchexpr pfn popt printfont pumheight redrawtime rightleft rtp sbo scrolljump sel shell shelltype showbreak si smartcase softtabstop spelllang sps sta su swb syntax taglength tbidi terse tildeop titlestring top ttimeout ttym uc undolevels vb vfile visualbell wc wh wildcharm wim winminheight wmh wrapscan ww
diff --git a/src/option.c b/src/option.c
index f38e9c7..e7d4c64 100644
--- a/src/option.c
+++ b/src/option.c
@@ -209,6 +209,7 @@
 #endif
 #define PV_NU		OPT_WIN(WV_NU)
 #define PV_RNU		OPT_WIN(WV_RNU)
+#define PV_LNR		OPT_WIN(WV_LNR)
 #ifdef FEAT_LINEBREAK
 # define PV_NUW		OPT_WIN(WV_NUW)
 #endif
@@ -1660,6 +1661,9 @@ static struct vimoption
 			    (char_u *)NULL, PV_NONE,
 #endif
 			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+    {"linenumber", "lnr",   P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+			    (char_u *)VAR_WIN, PV_LNR,
+			    {(char_u *)"none", (char_u *)NULL} SCRIPTID_INIT},
     {"lines",	    NULL,   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
 			    (char_u *)&Rows, PV_NONE,
 			    {
@@ -2945,6 +2949,7 @@ static char *(p_wop_values[]) = {"tagfile", NULL};
 #ifdef FEAT_WAK
 static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
 #endif
+static char *(p_lnr_values[]) = {"none", "number", "relative", "numrel", NULL};
 static char *(p_mousem_values[]) = {"extend", "popup", "popup_setpos", "mac", NULL};
 #ifdef FEAT_VISUAL
 static char *(p_sel_values[]) = {"inclusive", "exclusive", "old", NULL};
@@ -5617,6 +5622,33 @@ set_string_option(opt_idx, value, opt_flags)
     }
 }
 
+    static void
+set_line_number_style(wp, style)
+    win_T	*wp;
+    lnr_style_T	style;
+{
+    curwin->w_p_lnrsty = style;
+    switch(style)
+    {
+	case LNR_NONE:
+		curwin->w_p_nu = FALSE;
+		curwin->w_p_rnu = FALSE;
+		break;
+	case LNR_NUMBER:
+		curwin->w_p_nu = TRUE;
+		curwin->w_p_rnu = FALSE;
+		break;
+	case LNR_RELATIVE:
+		curwin->w_p_nu = FALSE;
+		curwin->w_p_rnu = TRUE;
+		break;
+	case LNR_NUMREL:
+		curwin->w_p_nu = FALSE;
+		curwin->w_p_rnu = TRUE;
+		break;
+    }
+}
+
 /*
  * Handle string options that need some action to perform when changed.
  * Returns NULL for success, or an error message for an error.
@@ -5738,6 +5770,32 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
 	}
     }
 
+    /* 'linenumber' */
+    else if (varp == &curwin->w_p_lnr)
+    {
+	if (check_opt_strings(curwin->w_p_lnr, p_lnr_values, FALSE) != OK)
+	    errmsg = e_invarg;
+	else if (STRCMP(curwin->w_p_lnr, oldval) != 0)
+	{
+	    if (STRCMP(curwin->w_p_lnr, "none") == 0)
+	    {
+		set_line_number_style(curwin, LNR_NONE);
+	    }
+	    else if (STRCMP(curwin->w_p_lnr, "number") == 0)
+	    {
+		set_line_number_style(curwin, LNR_NUMBER);
+	    }
+	    else if (STRCMP(curwin->w_p_lnr, "relative") == 0)
+	    {
+		set_line_number_style(curwin, LNR_RELATIVE);
+	    }
+	    else if (STRCMP(curwin->w_p_lnr, "numrel") == 0)
+	    {
+		set_line_number_style(curwin, LNR_NUMREL);
+	    }
+	}
+    }
+
 #ifdef FEAT_SYN_HL
     /* 'colorcolumn' */
     else if (varp == &curwin->w_p_cc)
@@ -7638,9 +7696,17 @@ set_bool_option(opt_idx, varp, value, opt_flags)
 	/* If 'number' is set, reset 'relativenumber'. */
 	/* If 'relativenumber' is set, reset 'number'. */
 	if ((int *)varp == &curwin->w_p_nu && curwin->w_p_nu)
-	    curwin->w_p_rnu = FALSE;
+	{
+	    set_line_number_style(curwin, LNR_NUMBER);
+	    set_string_option_direct((char_u *)"lnr", -1,
+					"number", OPT_FREE, SID_NONE);
+	}
 	if ((int *)varp == &curwin->w_p_rnu && curwin->w_p_rnu)
-	    curwin->w_p_nu = FALSE;
+	{
+	    set_line_number_style(curwin, LNR_RELATIVE);
+	    set_string_option_direct((char_u *)"lnr", -1,
+					"relative", OPT_FREE, SID_NONE);
+	}
     }
 
     else if ((int *)varp == &curbuf->b_p_ro)
@@ -9671,6 +9737,7 @@ get_varp(p)
 #endif
 	case PV_NU:	return (char_u *)&(curwin->w_p_nu);
 	case PV_RNU:	return (char_u *)&(curwin->w_p_rnu);
+	case PV_LNR:	return (char_u *)&(curwin->w_p_lnr);
 #ifdef FEAT_LINEBREAK
 	case PV_NUW:	return (char_u *)&(curwin->w_p_nuw);
 #endif
@@ -9864,6 +9931,8 @@ copy_winopt(from, to)
     to->wo_list = from->wo_list;
     to->wo_nu = from->wo_nu;
     to->wo_rnu = from->wo_rnu;
+    to->wo_lnr = vim_strsave(from->wo_lnr);
+    to->wo_lnrsty = from->wo_lnrsty;
 #ifdef FEAT_LINEBREAK
     to->wo_nuw = from->wo_nuw;
 #endif
diff --git a/src/option.h b/src/option.h
index 3474d8e..9389a7c 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1071,6 +1071,7 @@ enum
 #endif
     , WV_NU
     , WV_RNU
+    , WV_LNR
 #ifdef FEAT_LINEBREAK
     , WV_NUW
 #endif
@@ -1105,3 +1106,11 @@ enum
     , WV_WRAP
     , WV_COUNT	    /* must be the last one */
 };
+
+/* Line number style */
+typedef enum {
+      LNR_NONE = 0	/* Do not show line number */
+    , LNR_NUMBER	/* Show actual line number */
+    , LNR_RELATIVE	/* Show relative line number */
+    , LNR_NUMREL	/* Show actual and relative line number */
+} lnr_style_T;
diff --git a/src/screen.c b/src/screen.c
index 6d2345c..fb1cb61 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -433,7 +433,7 @@ update_screen(type)
     /* Force redraw when width of 'number' or 'relativenumber' column
      * changes. */
     if (curwin->w_redr_type < NOT_VALID
-	   && curwin->w_nrwidth != ((curwin->w_p_nu || curwin->w_p_rnu)
+	   && curwin->w_nrwidth != ((curwin->w_p_lnrsty != LNR_NONE)
 				    ? number_width(curwin) : 0))
 	curwin->w_redr_type = NOT_VALID;
 #endif
@@ -958,7 +958,7 @@ win_update(wp)
 #ifdef FEAT_LINEBREAK
     /* Force redraw when width of 'number' or 'relativenumber' column
      * changes. */
-    i = (wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) : 0;
+    i = (wp->w_p_lnrsty != LNR_NONE) ? number_width(wp) : 0;
     if (wp->w_nrwidth != i)
     {
 	type = NOT_VALID;
@@ -2312,7 +2312,7 @@ fold_line(wp, fold_count, foldinfo, lnum, row)
     /*
      * 3. Add the 'number' or 'relativenumber' column
      */
-    if (wp->w_p_nu || wp->w_p_rnu)
+    if (wp->w_p_lnrsty != LNR_NONE)
     {
 	len = W_WIDTH(wp) - col;
 	if (len > 0)
@@ -2324,14 +2324,15 @@ fold_line(wp, fold_count, foldinfo, lnum, row)
 	    if (len > w + 1)
 		len = w + 1;
 
-	    if (wp->w_p_nu)
+	    if (wp->w_p_lnrsty == LNR_NUMBER)
 		/* 'number' */
 		num = (long)lnum;
-	    else
+	    else if (wp->w_p_lnrsty == LNR_RELATIVE ||
+		     wp->w_p_lnrsty == LNR_NUMREL)
 	    {
 		/* 'relativenumber', don't use negative numbers */
 		num = labs((long)get_cursor_rel_lnum(wp, lnum));
-		if (num == 0)
+		if (wp->w_p_lnrsty == LNR_NUMREL && num == 0)
 		{
 		    num = lnum;
 		    fmt = "%-*ld ";
@@ -3477,7 +3478,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		draw_state = WL_NR;
 		/* Display the absolute or relative line number. After the
 		 * first fill with blanks when the 'n' flag isn't in 'cpo' */
-		if ((wp->w_p_nu || wp->w_p_rnu)
+		if ((wp->w_p_lnrsty != LNR_NONE)
 			&& (row == startrow
 #ifdef FEAT_DIFF
 			    + filler_lines
@@ -3494,14 +3495,15 @@ win_line(wp, lnum, startrow, endrow, nochange)
 			long num;
 			char *fmt = "%*ld ";
 
-			if (wp->w_p_nu)
+			if (wp->w_p_lnrsty == LNR_NUMBER)
 			    /* 'number' */
 			    num = (long)lnum;
-			else
+			else if (wp->w_p_lnrsty == LNR_RELATIVE ||
+				 wp->w_p_lnrsty == LNR_NUMREL)
 			{
 			    /* 'relativenumber', don't use negative numbers */
 			    num = labs((long)get_cursor_rel_lnum(wp, lnum));
-			    if (num == 0)
+			    if (wp->w_p_lnrsty == LNR_NUMREL && num == 0)
 			    {
 				num = lnum;
 				fmt = "%-*ld ";
@@ -10255,7 +10257,12 @@ number_width(wp)
     int		n;
     linenr_T	lnum;
 
-    lnum = wp->w_buffer->b_ml.ml_line_count;
+    if (wp->w_p_lnrsty == LNR_NUMBER || wp->w_p_lnrsty == LNR_NUMREL)
+	/* 'number', or linenumber=numrel */
+	lnum = wp->w_buffer->b_ml.ml_line_count;
+    else if (wp->w_p_lnrsty == LNR_RELATIVE)
+	/* 'relativenumber' */
+	lnum = wp->w_height;
 
     if (lnum == wp->w_nrwidth_line_count)
 	return wp->w_nrwidth_width;
diff --git a/src/structs.h b/src/structs.h
index 36440c3..3a6b721 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -171,6 +171,12 @@ typedef struct
 #define w_p_nu w_onebuf_opt.wo_nu	/* 'number' */
     int		wo_rnu;
 #define w_p_rnu w_onebuf_opt.wo_rnu	/* 'relativenumber' */
+    char_u	*wo_lnr;
+#define w_p_lnr w_onebuf_opt.wo_lnr	/* 'linenumber' */
+    lnr_style_T	wo_lnrsty;
+#define w_p_lnrsty \
+	    w_onebuf_opt.wo_lnrsty	/* Possible line number styles.
+					   See lnr_style_T */
 #ifdef FEAT_LINEBREAK
     long	wo_nuw;
 # define w_p_nuw w_onebuf_opt.wo_nuw	/* 'numberwidth' */
