diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/edit.c | 2 | ||||
-rw-r--r-- | src/ex_cmds.c | 1 | ||||
-rw-r--r-- | src/gui.c | 2 | ||||
-rw-r--r-- | src/misc1.c | 4 | ||||
-rw-r--r-- | src/misc2.c | 51 | ||||
-rw-r--r-- | src/move.c | 32 | ||||
-rw-r--r-- | src/netbeans.c | 3 | ||||
-rw-r--r-- | src/normal.c | 5 | ||||
-rw-r--r-- | src/option.c | 16 | ||||
-rw-r--r-- | src/option.h | 1 | ||||
-rw-r--r-- | src/proto/misc2.pro | 1 | ||||
-rw-r--r-- | src/screen.c | 64 | ||||
-rw-r--r-- | src/structs.h | 5 |
13 files changed, 148 insertions, 39 deletions
diff --git a/src/edit.c b/src/edit.c index 33e580f1b..88943cd7f 100644 --- a/src/edit.c +++ b/src/edit.c @@ -6272,7 +6272,7 @@ comp_textwidth(ff) ) textwidth -= 1; #endif - if (curwin->w_p_nu) + if (curwin->w_p_nu || curwin->w_p_rnu) textwidth -= 8; } if (textwidth < 0) diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 2296c332b..1f9a7f217 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3488,6 +3488,7 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin) curbuf->b_p_ma = FALSE; /* not modifiable */ curbuf->b_p_bin = FALSE; /* reset 'bin' before reading file */ curwin->w_p_nu = 0; /* no line numbers */ + curwin->w_p_rnu = 0; /* no relative line numbers */ #ifdef FEAT_SCROLLBIND curwin->w_p_scb = FALSE; /* no scroll binding */ #endif @@ -4412,7 +4412,7 @@ gui_update_horiz_scrollbar(force) max += W_WIDTH(curwin) - 1; #endif /* The line number isn't scrolled, thus there is less space when - * 'number' is set (also for 'foldcolumn'). */ + * 'number' or 'relativenumber' is set (also for 'foldcolumn'). */ size -= curwin_col_off(); #ifndef SCROLL_PAST_END max -= curwin_col_off(); diff --git a/src/misc1.c b/src/misc1.c index d476f31ed..69bfe7dbe 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -1742,7 +1742,7 @@ plines_win_nofold(wp, lnum) col += 1; /* - * Add column offset for 'number' and 'foldcolumn'. + * Add column offset for 'number', 'relativenumber' and 'foldcolumn'. */ width = W_WIDTH(wp) - win_col_off(wp); if (width <= 0) @@ -1803,7 +1803,7 @@ plines_win_col(wp, lnum, column) col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL) - 1; /* - * Add column offset for 'number', 'foldcolumn', etc. + * Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. */ width = W_WIDTH(wp) - win_col_off(wp); if (width <= 0) diff --git a/src/misc2.c b/src/misc2.c index 949d7e21a..8cd568304 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -469,6 +469,57 @@ decl(lp) } /* + * Get the line number relative to the current cursor position, i.e. the + * difference between line number and cursor position. Only look for lines that + * can be visible, folded lines don't count. + */ + linenr_T +get_cursor_rel_lnum(wp, lnum) + win_T *wp; + linenr_T lnum; /* line number to get the result for */ +{ + linenr_T cursor = wp->w_cursor.lnum; + linenr_T retval = 0; + +#ifdef FEAT_FOLDING + if (hasAnyFolding(wp)) + { + if (lnum > cursor) + { + while (lnum > cursor) + { + (void)hasFolding(lnum, &lnum, NULL); + /* if lnum and cursor are in the same fold, + * now lnum <= cursor */ + if (lnum > cursor) + retval++; + lnum--; + } + } + else if (lnum < cursor) + { + while (lnum < cursor) + { + (void)hasFolding(lnum, NULL, &lnum); + /* if lnum and cursor are in the same fold, + * now lnum >= cursor */ + if (lnum < cursor) + retval--; + lnum++; + } + } + /* else if (lnum == cursor) + * retval = 0; + */ + } + else +#endif + retval = lnum - cursor; + + return retval; +} + +/* * Make sure curwin->w_cursor.lnum is valid. */ void diff --git a/src/move.c b/src/move.c index de1a9e4de..4bdb69471 100644 --- a/src/move.c +++ b/src/move.c @@ -916,14 +916,14 @@ validate_cursor_col() } /* - * Compute offset of a window, occupied by line number, fold column and sign - * column (these don't move when scrolling horizontally). + * Compute offset of a window, occupied by absolute or relative line number, + * fold column and sign column (these don't move when scrolling horizontally). */ int win_col_off(wp) win_T *wp; { - return ((wp->w_p_nu ? number_width(wp) + 1 : 0) + return (((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0) #ifdef FEAT_CMDWIN + (cmdwin_type == 0 || wp != curwin ? 0 : 1) #endif @@ -949,13 +949,14 @@ curwin_col_off() /* * Return the difference in column offset for the second screen line of a - * wrapped line. It's 8 if 'number' is on and 'n' is in 'cpoptions'. + * wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in + * 'cpoptions'. */ int win_col_off2(wp) win_T *wp; { - if (wp->w_p_nu && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) + if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) return number_width(wp) + 1; return 0; } @@ -1218,17 +1219,22 @@ curs_columns(scroll) if (prev_skipcol != curwin->w_skipcol) redraw_later(NOT_VALID); + /* Redraw when w_row changes and 'relativenumber' is set */ + if (((curwin->w_valid & VALID_WROW) == 0 && (curwin->w_p_rnu #ifdef FEAT_SYN_HL - /* Redraw when w_virtcol changes and 'cursorcolumn' is set, or when w_row - * changes and 'cursorline' is set. */ - if (((curwin->w_p_cuc && (curwin->w_valid & VALID_VIRTCOL) == 0) - || (curwin->w_p_cul && (curwin->w_valid & VALID_WROW) == 0)) + /* or when w_row changes and 'cursorline' is set. */ + || curwin->w_p_cul +#endif + )) +#ifdef FEAT_SYN_HL + /* or when w_virtcol changes and 'cursorcolumn' is set */ + || (curwin->w_p_cuc && (curwin->w_valid & VALID_VIRTCOL) == 0) +#endif + ) # ifdef FEAT_INS_EXPAND - && !pum_visible() + if (!pum_visible()) # endif - ) - redraw_later(SOME_VALID); -#endif + redraw_later(SOME_VALID); curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL; } diff --git a/src/netbeans.c b/src/netbeans.c index 94c1aaadf..93a9aea75 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -3143,7 +3143,8 @@ netbeans_button_release(int button) if (bufno >= 0 && curwin != NULL && curwin->w_buffer == curbuf) { - int col = mouse_col - W_WINCOL(curwin) - (curwin->w_p_nu ? 9 : 1); + int col = mouse_col - W_WINCOL(curwin) + - ((curwin->w_p_nu || curwin->w_p_rnu) ? 9 : 1); long off = pos2off(curbuf, &curwin->w_cursor); /* sync the cursor position */ diff --git a/src/normal.c b/src/normal.c index a19771b4f..e02c81781 100644 --- a/src/normal.c +++ b/src/normal.c @@ -7845,8 +7845,9 @@ nv_g_cmd(cap) } else i = curwin->w_leftcol; - /* Go to the middle of the screen line. When 'number' is on and lines - * are wrapping the middle can be more to the left. */ + /* Go to the middle of the screen line. When 'number' or + * 'relativenumber' is on and lines are wrapping the middle can be more + * to the left. */ if (cap->nchar == 'm') i += (W_WIDTH(curwin) - curwin_col_off() + ((curwin->w_p_wrap && i > 0) diff --git a/src/option.c b/src/option.c index f93d839cc..c9cad3208 100644 --- a/src/option.c +++ b/src/option.c @@ -207,6 +207,7 @@ # define PV_LBR OPT_WIN(WV_LBR) #endif #define PV_NU OPT_WIN(WV_NU) +#define PV_RNU OPT_WIN(WV_RNU) #ifdef FEAT_LINEBREAK # define PV_NUW OPT_WIN(WV_NUW) #endif @@ -2015,6 +2016,9 @@ static struct vimoption (char_u *)NULL, PV_NONE, #endif {(char_u *)2000L, (char_u *)0L} SCRIPTID_INIT}, + {"relativenumber", "rnu", P_BOOL|P_VI_DEF|P_RWIN, + (char_u *)VAR_WIN, PV_RNU, + {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT}, {"remap", NULL, P_BOOL|P_VI_DEF, (char_u *)&p_remap, PV_NONE, {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT}, @@ -7230,10 +7234,18 @@ set_bool_option(opt_idx, varp, value, opt_flags) /* 'list', 'number' */ else if ((int *)varp == &curwin->w_p_list - || (int *)varp == &curwin->w_p_nu) + || (int *)varp == &curwin->w_p_nu + || (int *)varp == &curwin->w_p_rnu) { if (curwin->w_curswant != MAXCOL) curwin->w_set_curswant = TRUE; + + /* 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; + if ((int *)varp == &curwin->w_p_rnu && curwin->w_p_rnu) + curwin->w_p_nu = FALSE; } else if ((int *)varp == &curbuf->b_p_ro) @@ -9232,6 +9244,7 @@ get_varp(p) case PV_FMR: return (char_u *)&(curwin->w_p_fmr); #endif case PV_NU: return (char_u *)&(curwin->w_p_nu); + case PV_RNU: return (char_u *)&(curwin->w_p_rnu); #ifdef FEAT_LINEBREAK case PV_NUW: return (char_u *)&(curwin->w_p_nuw); #endif @@ -9417,6 +9430,7 @@ copy_winopt(from, to) #endif to->wo_list = from->wo_list; to->wo_nu = from->wo_nu; + to->wo_rnu = from->wo_rnu; #ifdef FEAT_LINEBREAK to->wo_nuw = from->wo_nuw; #endif diff --git a/src/option.h b/src/option.h index cfa7692cb..b635db175 100644 --- a/src/option.h +++ b/src/option.h @@ -1039,6 +1039,7 @@ enum , WV_LBR #endif , WV_NU + , WV_RNU #ifdef FEAT_LINEBREAK , WV_NUW #endif diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro index 261ec8226..5c4cc4210 100644 --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -11,6 +11,7 @@ int incl __ARGS((pos_T *lp)); int dec_cursor __ARGS((void)); int dec __ARGS((pos_T *lp)); int decl __ARGS((pos_T *lp)); +linenr_T get_cursor_rel_lnum __ARGS((win_T *wp, linenr_T lnum)); void check_cursor_lnum __ARGS((void)); void check_cursor_col __ARGS((void)); void check_cursor __ARGS((void)); diff --git a/src/screen.c b/src/screen.c index 7f929ac0f..72a93da64 100644 --- a/src/screen.c +++ b/src/screen.c @@ -423,9 +423,11 @@ update_screen(type) check_for_delay(FALSE); #ifdef FEAT_LINEBREAK - /* Force redraw when width of 'number' column changes. */ + /* Force redraw when width of 'number' or 'relativenumber' column + * changes. */ if (curwin->w_redr_type < NOT_VALID - && curwin->w_nrwidth != (curwin->w_p_nu ? number_width(curwin) : 0)) + && curwin->w_nrwidth != ((curwin->w_p_nu || curwin->w_p_rnu) + ? number_width(curwin) : 0)) curwin->w_redr_type = NOT_VALID; #endif @@ -871,8 +873,9 @@ win_update(wp) #endif #ifdef FEAT_LINEBREAK - /* Force redraw when width of 'number' column changes. */ - i = wp->w_p_nu ? number_width(wp) : 0; + /* Force redraw when width of 'number' or 'relativenumber' column + * changes. */ + i = (wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) : 0; if (wp->w_nrwidth != i) { type = NOT_VALID; @@ -2118,7 +2121,7 @@ fold_line(wp, fold_count, foldinfo, lnum, row) /* Build the fold line: * 1. Add the cmdwin_type for the command-line window * 2. Add the 'foldcolumn' - * 3. Add the 'number' column + * 3. Add the 'number' or 'relativenumber' column * 4. Compose the text * 5. Add the text * 6. set highlighting for the Visual area an other text @@ -2180,7 +2183,8 @@ fold_line(wp, fold_count, foldinfo, lnum, row) ScreenAttrs[off + (p) + ri] = v #endif - /* Set all attributes of the 'number' column and the text */ + /* Set all attributes of the 'number' or 'relativenumber' column and the + * text */ RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col); #ifdef FEAT_SIGNS @@ -2206,18 +2210,27 @@ fold_line(wp, fold_count, foldinfo, lnum, row) #endif /* - * 3. Add the 'number' column + * 3. Add the 'number' or 'relativenumber' column */ - if (wp->w_p_nu) + if (wp->w_p_nu || wp->w_p_rnu) { len = W_WIDTH(wp) - col; if (len > 0) { int w = number_width(wp); + long num; if (len > w + 1) len = w + 1; - sprintf((char *)buf, "%*ld ", w, (long)lnum); + + if (wp->w_p_nu) + /* 'number' */ + num = (long)lnum; + else + /* 'relativenumber', don't use negative numbers */ + num = (long)abs((int)get_cursor_rel_lnum(wp, lnum)); + + sprintf((char *)buf, "%*ld ", w, num); #ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) /* the line number isn't reversed */ @@ -3327,9 +3340,9 @@ win_line(wp, lnum, startrow, endrow, nochange) if (draw_state == WL_NR - 1 && n_extra == 0) { draw_state = WL_NR; - /* Display the line number. After the first fill with blanks - * when the 'n' flag isn't in 'cpo' */ - if (wp->w_p_nu + /* 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) && (row == startrow #ifdef FEAT_DIFF + filler_lines @@ -3343,8 +3356,18 @@ win_line(wp, lnum, startrow, endrow, nochange) #endif ) { + long num; + + if (wp->w_p_nu) + /* 'number' */ + num = (long)lnum; + else + /* 'relativenumber', don't use negative numbers */ + num = (long)abs((int)get_cursor_rel_lnum(wp, + lnum)); + sprintf((char *)extra, "%*ld ", - number_width(wp), (long)lnum); + number_width(wp), num); if (wp->w_skipcol > 0) for (p_extra = extra; *p_extra == ' '; ++p_extra) *p_extra = '-'; @@ -4707,7 +4730,8 @@ win_line(wp, lnum, startrow, endrow, nochange) else --n_skip; - /* Only advance the "vcol" when after the 'number' column. */ + /* Only advance the "vcol" when after the 'number' or 'relativenumber' + * column. */ if (draw_state > WL_NR #ifdef FEAT_DIFF && filler_todo <= 0 @@ -9770,8 +9794,8 @@ win_redr_ruler(wp, always) #if defined(FEAT_LINEBREAK) || defined(PROTO) /* - * Return the width of the 'number' column. - * Caller may need to check if 'number' is set. + * Return the width of the 'number' and 'relativenumber' column. + * Caller may need to check if 'number' or 'relativenumber' is set. * Otherwise it depends on 'numberwidth' and the line count. */ int @@ -9781,7 +9805,13 @@ number_width(wp) int n; linenr_T lnum; - lnum = wp->w_buffer->b_ml.ml_line_count; + if (wp->w_p_nu) + /* 'number' */ + lnum = wp->w_buffer->b_ml.ml_line_count; + else + /* 'relativenumber' */ + lnum = wp->w_height; + if (lnum == wp->w_nrwidth_line_count) return wp->w_nrwidth_width; wp->w_nrwidth_line_count = lnum; diff --git a/src/structs.h b/src/structs.h index d434bfee4..72bd96cd4 100644 --- a/src/structs.h +++ b/src/structs.h @@ -169,6 +169,8 @@ typedef struct #define w_p_list w_onebuf_opt.wo_list /* 'list' */ int wo_nu; #define w_p_nu w_onebuf_opt.wo_nu /* 'number' */ + int wo_rnu; +#define w_p_rnu w_onebuf_opt.wo_rnu /* 'relativenumber' */ #ifdef FEAT_LINEBREAK long wo_nuw; # define w_p_nuw w_onebuf_opt.wo_nuw /* 'numberwidth' */ @@ -1907,7 +1909,8 @@ struct window_S recomputed */ #endif #ifdef FEAT_LINEBREAK - int w_nrwidth; /* width of 'number' column being used */ + int w_nrwidth; /* width of 'number' and 'relativenumber' + column being used */ #endif /* |