From de95ca68f7a2a072721e6dd690d5749a3d03eb09 Mon Sep 17 00:00:00 2001
From: Faissal Bensefia <faissaloo@gmail.com>
Date: Thu, 20 Oct 2016 09:44:29 +0100
Subject: [PATCH] new feature: the ability to show line numbers before the text

It can be activated with --linenumbers on the command line or with
'set linenumbers' in a nanorc file, and it can be toggled with M-#.

Signed-off-by: Faissal Bensefia <faissaloo@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@justemail.net>
---
 configure.ac     | 13 +++++++
 doc/man/nano.1   |  3 ++
 doc/man/nanorc.5 |  3 ++
 src/global.c     | 16 +++++++++
 src/move.c       |  9 ++---
 src/nano.c       | 23 ++++++++++++
 src/nano.h       |  3 +-
 src/proto.h      |  8 +++++
 src/rcfile.c     |  3 ++
 src/utils.c      | 41 ++++++++++++++++++---
 src/winio.c      | 92 +++++++++++++++++++++++++++++++-----------------
 11 files changed, 172 insertions(+), 42 deletions(-)

diff --git a/configure.ac b/configure.ac
index e024a1e6..ed486b2a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,19 @@ fi
 AC_ARG_ENABLE(libmagic,
 AS_HELP_STRING([--disable-libmagic], [Disable detection of file types via libmagic]))
 
+AC_ARG_ENABLE(linenumbers,
+AS_HELP_STRING([--disable-linenumbers], [Disable line numbering]))
+if test "x$enable_tiny" = xyes; then
+    if test "x$enable_linenumbers" != xyes; then
+	enable_linenumbers=no
+    fi
+fi
+if test "x$disable_linenumbers" != xyes; then
+    if test "x$enable_linenumbers" != xno; then
+	AC_DEFINE(ENABLE_LINENUMBERS, 1, [Define this to enable line numbering.])
+    fi
+fi
+
 AC_ARG_ENABLE(mouse,
 AS_HELP_STRING([--disable-mouse], [Disable mouse support (and -m flag)]))
 if test "x$enable_mouse" = xno; then
diff --git a/doc/man/nano.1 b/doc/man/nano.1
index b63f73c1..247a497f 100644
--- a/doc/man/nano.1
+++ b/doc/man/nano.1
@@ -183,6 +183,9 @@ editing source code.
 Make the 'Cut Text' command (normally ^K) cut from the current cursor
 position to the end of the line, instead of cutting the entire line.
 .TP
+.BR \-l ", " \-\-linenumbers
+Display line numbers to the left of the text area.
+.TP
 .BR \-m ", " \-\-mouse
 Enable mouse support, if available for your system.  When enabled, mouse
 clicks can be used to place the cursor, set the mark (with a double
diff --git a/doc/man/nanorc.5 b/doc/man/nanorc.5
index 053c9fe2..6fec53a6 100644
--- a/doc/man/nanorc.5
+++ b/doc/man/nanorc.5
@@ -116,6 +116,9 @@ Specify the color combination to use for the shortcut key combos
 in the two help lines at the bottom of the screen.
 See \fBset titlecolor\fR for more details.
 .TP
+.B set linenumbers
+Display line numbers to the left of the text area.
+.TP
 .B set locking
 Enable vim-style lock-files for when editing files.
 .TP
diff --git a/src/global.c b/src/global.c
index 402575f0..babdbc90 100644
--- a/src/global.c
+++ b/src/global.c
@@ -45,6 +45,17 @@ bool shift_held;
 bool focusing = TRUE;
 	/* Whether an update of the edit window should center the cursor. */
 
+int margin = 0;
+	/* The amount of space reserved at the left for line numbers. */
+int editwincols = -1;
+	/* The number of usable columns in the edit window: COLS - margin. */
+#ifdef ENABLE_LINENUMBERS
+int last_drawn_line = 0;
+        /* The line number of the last drawn line. */
+int last_line_y;
+        /* The y coordinate of the last drawn line. */
+#endif
+
 message_type lastmessage = HUSH;
 	/* Messages of type HUSH should not overwrite type MILD nor ALERT. */
 
@@ -1154,6 +1165,9 @@ void shortcut_init(void)
     add_to_sclist(MMAIN, "M-O", 0, do_toggle_void, MORE_SPACE);
     add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, SMOOTH_SCROLL);
     add_to_sclist(MMAIN, "M-$", 0, do_toggle_void, SOFTWRAP);
+#ifdef ENABLE_LINENUMBERS
+    add_to_sclist(MMAIN, "M-#", 0, do_toggle_void, LINE_NUMBERS);
+#endif
     add_to_sclist(MMAIN, "M-P", 0, do_toggle_void, WHITESPACE_DISPLAY);
 #ifndef DISABLE_COLOR
     add_to_sclist(MMAIN, "M-Y", 0, do_toggle_void, NO_COLOR_SYNTAX);
@@ -1332,6 +1346,8 @@ const char *flagtostr(int flag)
 	    return N_("No conversion from DOS/Mac format");
 	case SUSPEND:
 	    return N_("Suspension");
+	case LINE_NUMBERS:
+	    return N_("Line numbering");
 	default:
 	    return "?????";
     }
diff --git a/src/move.c b/src/move.c
index afce2a42..b13b9beb 100644
--- a/src/move.c
+++ b/src/move.c
@@ -367,7 +367,7 @@ void do_next_word_void(void)
 void ensure_line_is_visible(void)
 {
 #ifndef NANO_TINY
-    if (ISSET(SOFTWRAP) && strlenpt(openfile->current->data) / COLS +
+    if (ISSET(SOFTWRAP) && strlenpt(openfile->current->data) / editwincols +
 				openfile->current_y >= editwinrows) {
 	edit_update(ISSET(SMOOTH_SCROLL) ? FLOWING : CENTERING);
 	refresh_needed = TRUE;
@@ -492,13 +492,14 @@ void do_down(bool scroll_only)
 #ifndef NANO_TINY
     if (ISSET(SOFTWRAP)) {
 	/* Compute the number of lines to scroll. */
-	amount = strlenpt(openfile->current->data) / COLS - xplustabs() / COLS +
-			strlenpt(openfile->current->next->data) / COLS +
+	amount = strlenpt(openfile->current->data) / editwincols -
+			xplustabs() / editwincols +
+			strlenpt(openfile->current->next->data) / editwincols +
 			openfile->current_y - editwinrows + 2;
 	topline = openfile->edittop;
 	/* Reduce the amount when there are overlong lines at the top. */
 	for (enough = 1; enough < amount; enough++) {
-	    amount -= strlenpt(topline->data) / COLS;
+	    amount -= strlenpt(topline->data) / editwincols;
 	    if (amount > 0)
 		topline = topline->next;
 	    if (amount < enough) {
diff --git a/src/nano.c b/src/nano.c
index 6cd68daa..d1ee039b 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -884,6 +884,9 @@ void usage(void)
     print_opt("-i", "--autoindent", N_("Automatically indent new lines"));
     print_opt("-k", "--cut", N_("Cut from cursor to end of line"));
 #endif
+#ifdef ENABLE_LINENUMBERS
+    print_opt("-l", "--linenumbers", N_("Show line numbers in front of the text"));
+#endif
 #ifndef DISABLE_MOUSE
     print_opt("-m", "--mouse", N_("Enable the use of the mouse"));
 #endif
@@ -962,6 +965,9 @@ void version(void)
 #ifdef HAVE_LIBMAGIC
     printf(" --enable-libmagic");
 #endif
+#ifdef ENABLE_LINENUMBERS
+    printf(" --enable-linenumbers");
+#endif
 #ifndef DISABLE_MOUSE
     printf(" --enable-mouse");
 #endif
@@ -1008,6 +1014,9 @@ void version(void)
 #ifndef HAVE_LIBMAGIC
     printf(" --disable-libmagic");
 #endif
+#ifndef ENABLE_LINENUMBERS
+    printf(" --disable-linenumbers");
+#endif
 #ifdef DISABLE_MOUSE
     printf(" --disable-mouse");
 #endif
@@ -1340,6 +1349,7 @@ void regenerate_screen(void)
     COLS = win.ws_col;
     LINES = win.ws_row;
 #endif
+    editwincols = COLS - margin;
 
 #ifdef USE_SLANG
     /* Slang curses emulation brain damage, part 1: If we just do what
@@ -1413,6 +1423,9 @@ void do_toggle(int flag)
 	    break;
 #ifndef DISABLE_COLOR
 	case NO_COLOR_SYNTAX:
+#endif
+#ifdef ENABLE_LINENUMBERS
+	case LINE_NUMBERS:
 #endif
 	case SOFTWRAP:
 	    edit_refresh();
@@ -1992,6 +2005,9 @@ int main(int argc, char **argv)
 	{"constantshow", 0, NULL, 'c'},
 	{"rebinddelete", 0, NULL, 'd'},
 	{"help", 0, NULL, 'h'},
+#ifdef ENABLE_LINENUMBERS
+	{"linenumbers", 0, NULL, 'l'},
+#endif
 #ifndef DISABLE_MOUSE
 	{"mouse", 0, NULL, 'm'},
 #endif
@@ -2270,6 +2286,11 @@ int main(int argc, char **argv)
 	    case '$':
 		SET(SOFTWRAP);
 		break;
+#endif
+#ifdef ENABLE_LINENUMBERS
+	    case 'l':
+		SET(LINE_NUMBERS);
+		break;
 #endif
 	    case 'h':
 		usage();
@@ -2542,6 +2563,8 @@ int main(int argc, char **argv)
      * dimensions. */
     window_init();
 
+    editwincols = COLS - margin;
+
     /* Set up the signal handlers. */
     signal_init();
 
diff --git a/src/nano.h b/src/nano.h
index 474e8c27..4e1e35f8 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -536,7 +536,8 @@ enum
     NOREAD_MODE,
     MAKE_IT_UNIX,
     JUSTIFY_TRIM,
-    SHOW_CURSOR
+    SHOW_CURSOR,
+    LINE_NUMBERS
 };
 
 /* Flags for the menus in which a given function should be present. */
diff --git a/src/proto.h b/src/proto.h
index b4087e90..1f3f804c 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -38,6 +38,13 @@ extern bool shift_held;
 
 extern bool focusing;
 
+extern int margin;
+extern int editwincols;
+#ifdef ENABLE_LINENUMBERS
+extern int last_drawn_line;
+extern int last_line_y;
+#endif
+
 extern message_type lastmessage;
 
 extern int controlleft;
@@ -675,6 +682,7 @@ void do_verbatim_input(void);
 
 /* All functions in utils.c. */
 void get_homedir(void);
+int digits(int n);
 bool parse_num(const char *str, ssize_t *val);
 bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
 void align(char **str);
diff --git a/src/rcfile.c b/src/rcfile.c
index 541c71a8..72a58808 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -35,6 +35,9 @@
 
 static const rcoption rcopts[] = {
     {"boldtext", BOLD_TEXT},
+#ifdef ENABLE_LINENUMBERS
+    {"linenumbers", LINE_NUMBERS},
+#endif
 #ifndef DISABLE_JUSTIFY
     {"brackets", 0},
 #endif
diff --git a/src/utils.c b/src/utils.c
index 54b38590..cbd5b55b 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -52,6 +52,39 @@ void get_homedir(void)
     }
 }
 
+#ifdef ENABLE_LINENUMBERS
+/* Return the number of digits that the given integer n takes up. */
+int digits(int n)
+{
+    if (n < 100000) {
+        if (n < 1000) {
+            if (n < 100)
+                return 2;
+            else
+                return 3;
+        } else {
+            if (n < 10000)
+                return 4;
+            else
+                return 5;
+        }
+    } else {
+        if (n < 10000000) {
+            if (n < 1000000)
+                return 6;
+            else
+                return 7;
+        }
+        else {
+            if (n < 100000000)
+                return 8;
+            else
+                return 9;
+        }
+    }
+}
+#endif
+
 /* Read a ssize_t from str, and store it in *val (if val is not NULL).
  * On error, we return FALSE and don't change *val.  Otherwise, we
  * return TRUE. */
@@ -430,12 +463,12 @@ char *free_and_assign(char *dest, char *src)
  * get_page_start(column) < COLS). */
 size_t get_page_start(size_t column)
 {
-    if (column == 0 || column < COLS - 1)
+    if (column == 0 || column < editwincols - 1)
 	return 0;
-    else if (COLS > 8)
-	return column - 7 - (column - 7) % (COLS - 8);
+    else if (editwincols > 8)
+	return column - 7 - (column - 7) % (editwincols - 8);
     else
-	return column - (COLS - 2);
+	return column - (editwincols - 2);
 }
 
 /* Return the placewewant associated with current_x, i.e. the zero-based
diff --git a/src/winio.c b/src/winio.c
index a1f6c0cf..d2d6e167 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1534,7 +1534,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
 	return -1;
 
     /* Save the screen coordinates where the mouse event took place. */
-    *mouse_x = mevent.x;
+    *mouse_x = mevent.x - margin;
     *mouse_y = mevent.y;
 
     in_bottomwin = wenclose(bottomwin, *mouse_y, *mouse_x);
@@ -1564,7 +1564,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
 	    if (*mouse_y == 0) {
 		/* Restore the untranslated mouse event coordinates, so
 		 * that they're relative to the entire screen again. */
-		*mouse_x = mevent.x;
+		*mouse_x = mevent.x - margin;
 		*mouse_y = mevent.y;
 
 		return 0;
@@ -2224,13 +2224,13 @@ void reset_cursor(void)
 	openfile->current_y = 0;
 
 	while (line != NULL && line != openfile->current) {
-	    openfile->current_y += strlenpt(line->data) / COLS + 1;
+	    openfile->current_y += strlenpt(line->data) / editwincols + 1;
 	    line = line->next;
 	}
-	openfile->current_y += xpt / COLS;
+	openfile->current_y += xpt / editwincols;
 
 	if (openfile->current_y < editwinrows)
-	    wmove(edit, openfile->current_y, xpt % COLS);
+	    wmove(edit, openfile->current_y, xpt % editwincols + margin);
     } else
 #endif
     {
@@ -2238,7 +2238,7 @@ void reset_cursor(void)
 				openfile->edittop->lineno;
 
 	if (openfile->current_y < editwinrows)
-	    wmove(edit, openfile->current_y, xpt - get_page_start(xpt));
+	    wmove(edit, openfile->current_y, xpt - get_page_start(xpt) + margin);
     }
 }
 
@@ -2257,7 +2257,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
     size_t startpos = actual_x(fileptr->data, start);
 	/* The position in fileptr->data of the leftmost character
 	 * that displays at least partially on the window. */
-    size_t endpos = actual_x(fileptr->data, start + COLS - 1) + 1;
+    size_t endpos = actual_x(fileptr->data, start + editwincols - 1) + 1;
 	/* The position in fileptr->data of the first character that is
 	 * completely off the window to the right.
 	 *
@@ -2266,11 +2266,33 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 #endif
 
     assert(openfile != NULL && fileptr != NULL && converted != NULL);
-    assert(strlenpt(converted) <= COLS);
+    assert(strlenpt(converted) <= editwincols);
+
+#ifdef ENABLE_LINENUMBERS
+    if (ISSET(LINE_NUMBERS)) {
+	/* If the line numbers now require more room, schedule a refresh. */
+	if (digits(openfile->filebot->lineno) + 1 != margin) {
+	    margin = digits(openfile->filebot->lineno) + 1;
+	    editwincols = COLS - margin;
+	    refresh_needed = TRUE;
+	}
+
+	/* Show the line number only for the non-softwrapped parts. */
+	wattron(edit, hilite_attribute);
+	if (last_drawn_line != fileptr->lineno || last_line_y >= line)
+	    mvwprintw(edit, line, 0, "%*i", margin - 1, fileptr->lineno);
+	else
+	    mvwprintw(edit, line, 0, "%*s", margin - 1, " ");
+	wattroff(edit, hilite_attribute);
+    } else {
+	margin = 0;
+	editwincols = COLS;
+    }
+#endif
 
     /* First simply paint the line -- then we'll add colors or the
      * marking highlight on just the pieces that need it. */
-    mvwaddstr(edit, line, 0, converted);
+    mvwaddstr(edit, line, margin, converted);
 
 #ifdef USING_OLD_NCURSES
     /* Tell ncurses to really redraw the line without trying to optimize
@@ -2348,7 +2370,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 
 			assert(0 <= x_start && 0 <= paintlen);
 
-			mvwaddnstr(edit, line, x_start, converted +
+			mvwaddnstr(edit, line, x_start + margin, converted +
 				index, paintlen);
 		    }
 		    k = startmatch.rm_eo;
@@ -2365,7 +2387,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 		if (fileptr->multidata[varnish->id] == CNONE)
 		    goto tail_of_loop;
 		else if (fileptr->multidata[varnish->id] == CWHOLELINE) {
-		    mvwaddnstr(edit, line, 0, converted, -1);
+		    mvwaddnstr(edit, line, margin, converted, -1);
 		    goto tail_of_loop;
 		} else if (fileptr->multidata[varnish->id] == CBEGINBEFORE) {
 		    regexec(varnish->end, fileptr->data, 1, &endmatch, 0);
@@ -2374,7 +2396,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 			goto tail_of_loop;
 		    paintlen = actual_x(converted, strnlenpt(fileptr->data,
 			endmatch.rm_eo) - start);
-		    mvwaddnstr(edit, line, 0, converted, paintlen);
+		    mvwaddnstr(edit, line, margin, converted, paintlen);
 		    goto tail_of_loop;
 		} if (fileptr->multidata[varnish->id] == -1)
 		    /* Assume this until proven otherwise below. */
@@ -2470,7 +2492,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
     fprintf(stderr, "  Marking for id %i  line %i as CBEGINBEFORE\n", varnish->id, line);
 #endif
 		}
-		mvwaddnstr(edit, line, 0, converted, paintlen);
+		mvwaddnstr(edit, line, margin, converted, paintlen);
 		/* If the whole line has been painted, don't bother looking
 		 * for any more starts. */
 		if (paintlen < 0)
@@ -2516,9 +2538,9 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 					strnlenpt(fileptr->data,
 					endmatch.rm_eo) - start - x_start);
 
-			    assert(0 <= x_start && x_start < COLS);
+			    assert(0 <= x_start && x_start < editwincols);
 
-			    mvwaddnstr(edit, line, x_start,
+			    mvwaddnstr(edit, line, x_start + margin,
 					converted + index, paintlen);
 			    if (paintlen > 0) {
 				fileptr->multidata[varnish->id] = CSTARTENDHERE;
@@ -2545,10 +2567,10 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 			if (end_line == NULL)
 			    break;
 
-			assert(0 <= x_start && x_start < COLS);
+			assert(0 <= x_start && x_start < editwincols);
 
 			/* Paint the rest of the line. */
-			mvwaddnstr(edit, line, x_start, converted + index, -1);
+			mvwaddnstr(edit, line, x_start + margin, converted + index, -1);
 			fileptr->multidata[varnish->id] = CENDAFTER;
 #ifdef DEBUG
     fprintf(stderr, "  Marking for id %i  line %i as CENDAFTER\n", varnish->id, line);
@@ -2626,11 +2648,15 @@ void edit_draw(filestruct *fileptr, const char *converted, int
 		paintlen = actual_x(converted + index, paintlen);
 
 	    wattron(edit, hilite_attribute);
-	    mvwaddnstr(edit, line, x_start, converted + index, paintlen);
+	    mvwaddnstr(edit, line, x_start + margin, converted + index, paintlen);
 	    wattroff(edit, hilite_attribute);
 	}
     }
 #endif /* !NANO_TINY */
+#ifdef ENABLE_LINENUMBERS
+    last_drawn_line = fileptr->lineno;
+    last_line_y = line;
+#endif
 }
 
 /* Just update one line in the edit buffer.  This is basically a wrapper
@@ -2654,7 +2680,7 @@ int update_line(filestruct *fileptr, size_t index)
 	filestruct *tmp;
 
 	for (tmp = openfile->edittop; tmp && tmp != fileptr; tmp = tmp->next)
-	    line += (strlenpt(tmp->data) / COLS) + 1;
+	    line += (strlenpt(tmp->data) / editwincols) + 1;
     } else
 #endif
 	line = fileptr->lineno - openfile->edittop->lineno;
@@ -2678,11 +2704,11 @@ int update_line(filestruct *fileptr, size_t index)
     /* Expand the line, replacing tabs with spaces, and control
      * characters with their displayed forms. */
 #ifdef NANO_TINY
-    converted = display_string(fileptr->data, page_start, COLS, TRUE);
+    converted = display_string(fileptr->data, page_start, editwincols, TRUE);
 #else
-    converted = display_string(fileptr->data, page_start, COLS, !ISSET(SOFTWRAP));
+    converted = display_string(fileptr->data, page_start, editwincols, !ISSET(SOFTWRAP));
 #ifdef DEBUG
-    if (ISSET(SOFTWRAP) && strlen(converted) >= COLS - 2)
+    if (ISSET(SOFTWRAP) && strlen(converted) >= editwincols - 2)
 	fprintf(stderr, "update_line(): converted(1) line = %s\n", converted);
 #endif
 #endif /* !NANO_TINY */
@@ -2695,13 +2721,13 @@ int update_line(filestruct *fileptr, size_t index)
     if (!ISSET(SOFTWRAP)) {
 #endif
 	if (page_start > 0)
-	    mvwaddch(edit, line, 0, '$');
-	if (strlenpt(fileptr->data) > page_start + COLS)
+	    mvwaddch(edit, line, margin, '$');
+	if (strlenpt(fileptr->data) > page_start + editwincols)
 	    mvwaddch(edit, line, COLS - 1, '$');
 #ifndef NANO_TINY
     } else {
 	size_t full_length = strlenpt(fileptr->data);
-	for (index += COLS; index <= full_length && line < editwinrows - 1; index += COLS) {
+	for (index += editwincols; index <= full_length && line < editwinrows - 1; index += editwincols) {
 	    line++;
 #ifdef DEBUG
 	    fprintf(stderr, "update_line(): softwrap code, moving to %d index %lu\n", line, (unsigned long)index);
@@ -2710,9 +2736,9 @@ int update_line(filestruct *fileptr, size_t index)
 
 	    /* Expand the line, replacing tabs with spaces, and control
 	     * characters with their displayed forms. */
-	    converted = display_string(fileptr->data, index, COLS, !ISSET(SOFTWRAP));
+	    converted = display_string(fileptr->data, index, editwincols, !ISSET(SOFTWRAP));
 #ifdef DEBUG
-	    if (ISSET(SOFTWRAP) && strlen(converted) >= COLS - 2)
+	    if (ISSET(SOFTWRAP) && strlen(converted) >= editwincols - 2)
 		fprintf(stderr, "update_line(): converted(2) line = %s\n", converted);
 #endif
 
@@ -2753,7 +2779,7 @@ void compute_maxrows(void)
     maxrows = 0;
     for (n = 0; n < editwinrows && foo; n++) {
 	maxrows++;
-	n += strlenpt(foo->data) / COLS;
+	n += strlenpt(foo->data) / editwincols;
 	foo = foo->next;
     }
 
@@ -2798,7 +2824,7 @@ void edit_scroll(scroll_dir direction, ssize_t nlines)
 #ifndef NANO_TINY
 	/* Don't over-scroll on long lines. */
 	if (ISSET(SOFTWRAP) && direction == UPWARD) {
-	    ssize_t len = strlenpt(openfile->edittop->data) / COLS;
+	    ssize_t len = strlenpt(openfile->edittop->data) / editwincols;
 	    i -= len;
 	    if (len > 0)
 		refresh_needed = TRUE;
@@ -2879,7 +2905,7 @@ void edit_redraw(filestruct *old_current)
     if (openfile->current->lineno >= openfile->edittop->lineno + maxrows ||
 #ifndef NANO_TINY
 		(openfile->current->lineno == openfile->edittop->lineno + maxrows - 1 &&
-		ISSET(SOFTWRAP) && strlenpt(openfile->current->data) >= COLS) ||
+		ISSET(SOFTWRAP) && strlenpt(openfile->current->data) >= editwincols) ||
 #endif
 		openfile->current->lineno < openfile->edittop->lineno) {
 	edit_update((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : FLOWING);
@@ -2978,7 +3004,7 @@ void edit_update(update_type manner)
 	    goal = editwinrows - 1;
 #ifndef NANO_TINY
 	    if (ISSET(SOFTWRAP))
-		goal -= strlenpt(openfile->current->data) / COLS ;
+		goal -= strlenpt(openfile->current->data) / editwincols;
 #endif
 	}
     } else {
@@ -2996,7 +3022,7 @@ void edit_update(update_type manner)
 	goal --;
 #ifndef NANO_TINY
 	if (ISSET(SOFTWRAP)) {
-	    goal -= strlenpt(openfile->edittop->data) / COLS;
+	    goal -= strlenpt(openfile->edittop->data) / editwincols;
 	    if (goal < 0)
 		openfile->edittop = openfile->edittop->next;
 	}
@@ -3118,7 +3144,7 @@ void spotlight(bool active, const char *word)
     size_t word_len = strlenpt(word), room;
 
     /* Compute the number of columns that are available for the word. */
-    room = COLS + get_page_start(xplustabs()) - xplustabs();
+    room = editwincols + get_page_start(xplustabs()) - xplustabs();
 
     assert(room > 0);
 
-- 
GitLab