diff --git a/doc/man/nanorc.5 b/doc/man/nanorc.5 index acacac3..5cb0a68 100644 --- a/doc/man/nanorc.5 +++ b/doc/man/nanorc.5 @@ -52,6 +52,11 @@ match \fB"\fP, \fB'\fP, \fB)\fP, \fB>\fP, \fB]\fP, and \fB}\fP. The supported commands and arguments are: .TP 3 +.B set linenumbers +When compiled with line numbering support will draw a line number 'ruler' +in the margin. +.B set hexlinenumbers +Like linenumbers but uses hexadecimal for the numbers in the ruler. .B set allow_insecure_backup When backing up files, allow the backup to succeed even if its permissions can't be (re)set due to special OS considerations. You should diff --git a/src/nano.h b/src/nano.h index 98ec049..49ea692 100644 --- a/src/nano.h +++ b/src/nano.h @@ -500,6 +500,8 @@ enum CONST_UPDATE, NO_HELP, SUSPEND, + LINE_NUM, + HEX_LINE_NUM, NO_WRAP, AUTOINDENT, VIEW_MODE, diff --git a/src/rcfile.c b/src/rcfile.c index 8face04..739e403 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -34,6 +34,10 @@ static const rcoption rcopts[] = { {"boldtext", BOLD_TEXT}, +#ifndef DISABLE_LINE_NUM + {"linenumbers", LINE_NUM}, + {"hexlinenumbers", HEX_LINE_NUM}, +#endif #ifndef DISABLE_JUSTIFY {"brackets", 0}, #endif diff --git a/src/revision.h b/src/revision.h new file mode 100644 index 0000000..dc1c99a --- /dev/null +++ b/src/revision.h @@ -0,0 +1 @@ +#define REVISION "v2.6.1-24-g4957c11" diff --git a/src/winio.c b/src/winio.c index b966c3f..a0a040e 100644 --- a/src/winio.c +++ b/src/winio.c @@ -35,6 +35,8 @@ #define BRANDING PACKAGE_STRING #endif +int margin=0; + static int *key_buffer = NULL; /* The keystroke buffer, containing all the keystrokes we * haven't handled yet at a given point. */ @@ -1485,7 +1487,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); @@ -1516,7 +1518,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; @@ -2171,13 +2173,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)) / (COLS-margin) + 1; line = line->next; } - openfile->current_y += xpt / COLS; + openfile->current_y += xpt / (COLS-margin); if (openfile->current_y < editwinrows) - wmove(edit, openfile->current_y, xpt % COLS); + wmove(edit, openfile->current_y, (xpt % (COLS-margin))+margin); } else #endif { @@ -2185,10 +2187,90 @@ 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); } } +int intlen(int n) +{ + if (n < 100000) + { + // 5 or less + if (n < 100){ + // 1 or 2 + if (n < 10) + return 1; + else + return 2; + } + else + { + // 3 or 4 or 5 + if (n < 1000) + { + return 3; + } + else + { + // 4 or 5 + if (n < 10000) + { + return 4; + } + else + { + return 5; + } + } + } + } + else + { + // 6 or more + if (n < 10000000) + { + // 6 or 7 + if (n < 1000000) + { + return 6; + } + else + { + return 7; + } + } + else + { + // 8 to 10 + if (n < 100000000) + { + return 8; + } + else + { + // 9 or 10 + if (n < 1000000000) + { + return 9; + } + else + { + return 10; + } + } + } + } +} +int hexlen(int n) +{ + int len=0; + while (n!=0) + { + n>>=4; //One hex digit = one nibble + len++; + } + return len; +} /* edit_draw() takes care of the job of actually painting a line into * the edit window. fileptr is the line to be painted, at row line of * the window. converted is the actual string to be written to the @@ -2200,6 +2282,24 @@ void reset_cursor(void) void edit_draw(filestruct *fileptr, const char *converted, int line, size_t start) { + #ifndef DISABLE_LINE_NUM + if (ISSET(LINE_NUM)) + { + margin = intlen(openfile->filebot->lineno)+3; + //Wouldn't it be cool if we added an option for hex representation? + wattron(edit,A_BOLD); + mvwprintw(edit,line,margin-(intlen(((long)openfile->edittop->lineno)+line)+2),"%i│",((long)openfile->edittop->lineno)+line); + wattroff(edit,A_BOLD); + } + else if (ISSET(HEX_LINE_NUM)) + { + margin = hexlen(openfile->filebot->lineno)+3; + //Wouldn't it be cool if we added an option for hex representation? + wattron(edit,A_BOLD); + mvwprintw(edit,line,margin-(hexlen(((long)openfile->edittop->lineno)+line)+2),"%X│",((long)openfile->edittop->lineno)+line); + wattroff(edit,A_BOLD); + } + #endif #if !defined(NANO_TINY) || !defined(DISABLE_COLOR) size_t startpos = actual_x(fileptr->data, start); /* The position in fileptr->data of the leftmost character @@ -2217,7 +2317,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int /* 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); #ifndef USE_SLANG /* Tell ncurses to really redraw the line without trying to optimize @@ -2297,7 +2397,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; @@ -2314,7 +2414,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); @@ -2323,7 +2423,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. */ @@ -2419,7 +2519,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) @@ -2467,7 +2567,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int assert(0 <= x_start && x_start < COLS); - mvwaddnstr(edit, line, x_start, + mvwaddnstr(edit, line, x_start+margin, converted + index, paintlen); if (paintlen > 0) { fileptr->multidata[varnish->id] = CSTARTENDHERE; @@ -2497,7 +2597,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int assert(0 <= x_start && x_start < COLS); /* 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); @@ -2573,10 +2673,10 @@ void edit_draw(filestruct *fileptr, const char *converted, int index = actual_x(converted, x_start); if (paintlen > 0) - paintlen = actual_x(converted + index, paintlen); + paintlen = actual_x(converted + index+margin, 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); } } @@ -2604,7 +2704,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)+margin) / COLS) + 1; } else #endif line = fileptr->lineno - openfile->edittop->lineno; @@ -2646,12 +2746,12 @@ int update_line(filestruct *fileptr, size_t index) #endif if (page_start > 0) mvwaddch(edit, line, 0, '$'); - if (strlenpt(fileptr->data) > page_start + COLS) + if (strlenpt(fileptr->data) > page_start + COLS-margin) 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 += COLS-margin; index <= full_length && line < editwinrows - 1; index += COLS-margin) { line++; #ifdef DEBUG fprintf(stderr, "update_line(): softwrap code, moving to %d index %lu\n", line, (unsigned long)index); @@ -2703,7 +2803,7 @@ void compute_maxrows(void) maxrows = 0; for (n = 0; n < editwinrows && foo; n++) { maxrows++; - n += strlenpt(foo->data) / COLS; + n += (strlenpt(foo->data)+margin) / COLS; foo = foo->next; } @@ -2748,7 +2848,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)+margin) / COLS; i -= len; if (len > 0) refresh_needed = TRUE; @@ -2944,7 +3044,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)+margin) / COLS; #endif } #ifdef DEBUG