nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit c33e5f78f29ad35e77eaf1a99e1454f6c8b2f2dd
parent 2ce71a1332a8f2215056f2a03f311aa18f2fa363
Author: bsandro <email@bsandro.tech>
Date:   Mon, 30 Jun 2025 01:10:25 +0300

new feature: relative line numbers.

When a config option "linerelnumbers" is used with the default line numbers
feature enabled (both on build and in config/command line) display line numbers
relative to the "active" line under the cursor. The active line number is the
actual one from top to avoid confusion and constant displaying "0" for it.

Modeled by the same vim/neovim feature.

Signed-off-by: bsandro <email@bsandro.tech>

Diffstat:
Mdoc/nano.texi | 3+++
Mdoc/sample.nanorc.in | 3+++
Msrc/definitions.h | 1+
Msrc/rcfile.c | 3+++
Msrc/winio.c | 11++++++++++-
Msyntax/nanorc.nanorc | 4++--
6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/doc/nano.texi b/doc/nano.texi @@ -1037,6 +1037,9 @@ if your terminal can do those. Display line numbers to the left of the text area. (Any line with an anchor additionally gets a mark in the margin.) +@item set linerelnumbers +Display relative line numbers (only works with linenumbers option enabled). + @item set locking Enable vim-style lock-files for when editing files. diff --git a/doc/sample.nanorc.in b/doc/sample.nanorc.in @@ -84,6 +84,9 @@ ## Display line numbers to the left (and any anchors in the margin). # set linenumbers +## Display relative line numbers (works only with linenumbers enabled) +# set linerelnumbers + ## Enable vim-style lock-files. This is just to let a vim user know you ## are editing a file [s]he is trying to edit and vice versa. There are ## no plans to implement vim-style undo state in these files. diff --git a/src/definitions.h b/src/definitions.h @@ -363,6 +363,7 @@ enum { TRIM_BLANKS, SHOW_CURSOR, LINE_NUMBERS, + LINE_REL_NUMBERS, AT_BLANKS, AFTER_ENDS, LET_THEM_ZAP, diff --git a/src/rcfile.c b/src/rcfile.c @@ -56,6 +56,7 @@ static const rcoption rcopts[] = { #endif #ifdef ENABLE_LINENUMBERS {"linenumbers", LINE_NUMBERS}, + {"linerelnumbers", LINE_REL_NUMBERS}, #endif #ifdef HAVE_LIBMAGIC {"magic", USE_MAGIC}, @@ -457,6 +458,8 @@ keystruct *strtosc(const char *input) #ifdef ENABLE_LINENUMBERS else if (!strcmp(input, "linenumbers")) s->toggle = LINE_NUMBERS; + else if (!strcmp(input, "linerelnumbers")) + s->toggle = LINE_REL_NUMBERS; #endif else if (!strcmp(input, "whitespacedisplay")) s->toggle = WHITESPACE_DISPLAY; diff --git a/src/winio.c b/src/winio.c @@ -2548,12 +2548,15 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col) * the text -- but only for the parts that are not softwrapped. */ if (margin > 0) { wattron(midwin, interface_color_pair[LINE_NUMBER]); + long int lineno = line->lineno; + if (ISSET(LINE_REL_NUMBERS) && openfile->current->lineno != line->lineno) + lineno = labs(openfile->current->lineno - line->lineno); #ifndef NANO_TINY if (ISSET(SOFTWRAP) && from_col != 0) mvwprintw(midwin, row, 0, "%*s", margin - 1, " "); else #endif - mvwprintw(midwin, row, 0, "%*zd", margin - 1, line->lineno); + mvwprintw(midwin, row, 0, "%*zd", margin - 1, lineno); wattroff(midwin, interface_color_pair[LINE_NUMBER]); #ifndef NANO_TINY if (line->has_anchor && (from_col == 0 || !ISSET(SOFTWRAP))) @@ -3336,6 +3339,12 @@ void edit_redraw(linestruct *old_current, update_type manner) openfile->placewewant = xplustabs(); + #ifdef ENABLE_LINENUMBERS + /* Full update is needed if relative line numbers are on */ + if (ISSET(LINE_NUMBERS) && ISSET(LINE_REL_NUMBERS) && old_current != openfile->current) + refresh_needed = TRUE; + #endif + /* If the current line is offscreen, scroll until it's onscreen. */ if (current_is_offscreen()) { adjust_viewport(ISSET(JUMPY_SCROLLING) ? CENTERING : manner); diff --git a/syntax/nanorc.nanorc b/syntax/nanorc.nanorc @@ -14,7 +14,7 @@ color bold,purple "^[[:blank:]]*include[[:blank:]]+[^[:blank:]"]+" color lime "^[[:blank:]]*extendsyntax[[:blank:]]+[[:alpha:]]+[[:blank:]]+(i?color|header|magic|comment|formatter|linter|tabgives)[[:blank:]]+.*" # The arguments of commands -color brightgreen "^[[:blank:]]*(set|unset)[[:blank:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|boldtext|bookstyle|breaklonglines|casesensitive|colonparsing|constantshow|cutfromcursor|emptyline|historylog|indicator|jumpyscrolling|linenumbers|locking|magic|minibar|mouse|multibuffer|noconvert|nohelp|nonewlines|positionlog|preserve|quickblank|rawsequences|rebinddelete|regexp|saveonexit|showcursor|smarthome|softwrap|stateflags|tabstospaces|trimblanks|unix|whitespacedisplay|wordbounds|zap|zero)\>" +color brightgreen "^[[:blank:]]*(set|unset)[[:blank:]]+(afterends|allow_insecure_backup|atblanks|autoindent|backup|boldtext|bookstyle|breaklonglines|casesensitive|colonparsing|constantshow|cutfromcursor|emptyline|historylog|indicator|jumpyscrolling|linenumbers|linerelnumbers|locking|magic|minibar|mouse|multibuffer|noconvert|nohelp|nonewlines|positionlog|preserve|quickblank|rawsequences|rebinddelete|regexp|saveonexit|showcursor|smarthome|softwrap|stateflags|tabstospaces|trimblanks|unix|whitespacedisplay|wordbounds|zap|zero)\>" color brightgreen "^[[:blank:]]*set[[:blank:]]+(backupdir|brackets|errorcolor|functioncolor|keycolor|matchbrackets|minicolor|numbercolor|operatingdir|promptcolor|punct|quotestr|scrollercolor|selectedcolor|speller|spotlightcolor|statuscolor|stripecolor|titlecolor|whitespace|wordchars)[[:blank:]]+" color brightgreen "^[[:blank:]]*set[[:blank:]]+(fill[[:blank:]]+-?[[:digit:]]+|(guidestripe|tabsize)[[:blank:]]+[1-9][0-9]*)\>" color brightgreen "^[[:blank:]]*bind[[:blank:]]+((\^([[:alpha:]]|[]/@\^_`-]|Space)|([Ss][Hh]-)?[Mm]-[[:alpha:]]|[Mm]-([][!"#$%&'()*+,./0-9:;<=>?@\^_`{|}~-]|Space))|F([1-9]|1[0-9]|2[0-4])|Ins|Del)[[:blank:]]+([[:lower:]]+|".*")[[:blank:]]+(main|help|search|replace(with)?|yesno|gotoline|writeout|insert|execute|browser|whereisfile|gotodir|spell|linter|all)\>" @@ -32,7 +32,7 @@ color crimson "\{(location|gotoline|(begin|end)para|comment|complete|(un)?indent color crimson "\{(left|right|up|down|home|end|(scroll|page)(up|down)|(top|bottom)row|center|cycle|(prev|next)(word|block|anchor|buf))\}" color crimson "\{(tab|enter|delete|backspace|verbatim|refresh|suspend|casesens|regexp|backwards|older|newer|(dos|mac)format)\}" color crimson "\{(append|prepend|backup|flip(goto|replace|execute|pipe|convert|newbuffer)|browser|gotodir|(first|last)(file|line))\}" -color crimson "\{(nohelp|constantshow|softwrap|linenumbers|whitespacedisplay|nosyntax|zero)\}" +color crimson "\{(nohelp|constantshow|softwrap|linenumbers|linerelnumbers|whitespacedisplay|nosyntax|zero)\}" color crimson "\{(smarthome|autoindent|cutfromcursor|breaklonglines|tabstospaces|mouse|\{)\}" # Commands