Index: src/files.c =================================================================== --- src/files.c (revision 5036) +++ src/files.c (working copy) @@ -414,6 +414,15 @@ color_init(); #endif + if (ISSET(SMOOTH_HORZ_SCROLL)) { + size_t curr_col =xplustabs(); + size_t pg_start = get_page_start(curr_col); + size_t old_pg_start = EDITWIN_CURR_PG_START; + + if (pg_start != old_pg_start) + set_edit_pg_start(pg_start); + } + /* Update the edit window. */ edit_refresh(); } Index: src/global.c =================================================================== --- src/global.c (revision 5036) +++ src/global.c (working copy) @@ -1431,6 +1431,8 @@ s->toggle = MORE_SPACE; else if (!strcasecmp(input, "smoothscroll")) s->toggle = SMOOTH_SCROLL; + else if (!strcasecmp(input, "align_page")) + s->toggle = SMOOTH_HORZ_SCROLL; else if (!strcasecmp(input, "softwrap")) s->toggle = SOFTWRAP; else if (!strcasecmp(input, "whitespacedisplay")) Index: src/move.c =================================================================== --- src/move.c (revision 5036) +++ src/move.c (working copy) @@ -29,21 +29,29 @@ /* Move to the first line of the file. */ void do_first_line(void) { + size_t pww_save = openfile->placewewant; openfile->current = openfile->edittop = openfile->fileage; openfile->current_x = 0; openfile->placewewant = 0; + if (ISSET(SMOOTH_HORZ_SCROLL) && need_horizontal_update(pww_save)) + update_page(); + else edit_refresh_needed = TRUE; } /* Move to the last line of the file. */ void do_last_line(void) { + size_t pww_save = openfile->placewewant; openfile->current = openfile->filebot; openfile->current_x = strlen(openfile->filebot->data); openfile->placewewant = xplustabs(); openfile->current_y = editwinrows - 1; + if (ISSET(SMOOTH_HORZ_SCROLL) && need_horizontal_update(pww_save)) + update_page(); + else edit_refresh_needed = TRUE; } @@ -226,8 +234,9 @@ size_t pww_save = openfile->placewewant; filestruct *current_save = openfile->current; char *char_mb; - int char_mb_len; - bool end_line = FALSE, started_on_word = FALSE; + int char_mb_len=0; + bool started_on_word = FALSE; + bool end_line = (openfile->current_x >= strlen(openfile->current->data)); assert(openfile->current != NULL && openfile->current->data != NULL); @@ -471,9 +480,13 @@ } #endif - if (need_horizontal_update(pww_save)) + if (need_horizontal_update(pww_save)) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + update_page(); + else update_line(openfile->current, openfile->current_x); } +} /* Move to the end of the current line. */ void do_end(void) @@ -483,9 +496,13 @@ openfile->current_x = strlen(openfile->current->data); openfile->placewewant = xplustabs(); - if (need_horizontal_update(pww_save)) + if (need_horizontal_update(pww_save)) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + update_page(); + else update_line(openfile->current, openfile->current_x); } +} /* If scroll_only is FALSE, move up one line. If scroll_only is TRUE, * scroll up one line without scrolling the cursor. */ @@ -534,11 +551,15 @@ * needs to be redrawn if we're not on the first page, and the * latter needs to be drawn unconditionally. */ if (openfile->current_y > 0) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + edit_refresh(); + else { if (need_vertical_update(0)) update_line(openfile->current->next, 0); update_line(openfile->current, openfile->current_x); } } +} /* Move up one line. */ void do_up_void(void) @@ -632,11 +653,15 @@ || ISSET(SOFTWRAP) #endif ) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + edit_refresh(); + else { if (need_vertical_update(0)) update_line(openfile->current->prev, 0); update_line(openfile->current, openfile->current_x); } } +} /* Move down one line. */ void do_down_void(void) @@ -671,9 +696,13 @@ openfile->placewewant = xplustabs(); - if (need_horizontal_update(pww_save)) + if (need_horizontal_update(pww_save)) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + update_page(); + else update_line(openfile->current, openfile->current_x); } +} /* Move right one character. */ void do_right(void) @@ -692,6 +721,10 @@ openfile->placewewant = xplustabs(); - if (need_horizontal_update(pww_save)) + if (need_horizontal_update(pww_save)) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + update_page(); + else update_line(openfile->current, openfile->current_x); } +} Index: src/nano.c =================================================================== --- src/nano.c (revision 5036) +++ src/nano.c (working copy) @@ -2032,6 +2032,9 @@ openfile->current->data = charealloc(openfile->current->data, current_len + (char_buf_len * 2)); + if (openfile->current_x > current_len) + openfile->current_x = current_len; + assert(openfile->current_x <= current_len); charmove(openfile->current->data + openfile->current_x + @@ -2090,7 +2093,9 @@ #ifndef DISABLE_COLOR reset_multis(openfile->current, FALSE); #endif - if (edit_refresh_needed == TRUE) { + if (ISSET(SMOOTH_HORZ_SCROLL)) + update_page(); + else if (edit_refresh_needed == TRUE) { edit_refresh(); edit_refresh_needed = FALSE; } else Index: src/nano.h =================================================================== --- src/nano.h (revision 5036) +++ src/nano.h (working copy) @@ -513,6 +513,7 @@ BACKWARDS_SEARCH, MULTIBUFFER, SMOOTH_SCROLL, + SMOOTH_HORZ_SCROLL, REBIND_DELETE, REBIND_KEYPAD, NO_CONVERT, @@ -537,6 +538,7 @@ NOREAD_MODE }; +#define EDITWIN_CURR_PG_START get_edit_pg_start() /* Flags for the menus in which a given function should be present. */ #define MMAIN (1<<0) #define MWHEREIS (1<<1) Index: src/proto.h =================================================================== --- src/proto.h (revision 5036) +++ src/proto.h (working copy) @@ -727,6 +727,8 @@ char *mallocstrcpy(char *dest, const char *src); char *mallocstrassn(char *dest, char *src); size_t get_page_start(size_t column); +size_t get_edit_pg_start(); +void set_edit_pg_start(size_t column); size_t xplustabs(void); size_t actual_x(const char *s, size_t column); size_t strnlenpt(const char *s, size_t maxlen); @@ -793,6 +795,7 @@ void edit_scroll(scroll_dir direction, ssize_t nlines); void edit_redraw(filestruct *old_current, size_t pww_save); void edit_refresh(void); +void update_page(void); void edit_update(update_type location); void total_redraw(void); void total_refresh(void); Index: src/rcfile.c =================================================================== --- src/rcfile.c (revision 5036) +++ src/rcfile.c (working copy) @@ -94,6 +94,7 @@ {"quickblank", QUICK_BLANK}, {"smarthome", SMART_HOME}, {"smooth", SMOOTH_SCROLL}, + {"align_page", SMOOTH_HORZ_SCROLL}, {"tabstospaces", TABS_TO_SPACES}, {"whitespace", 0}, {"wordbounds", WORD_BOUNDS}, Index: src/utils.c =================================================================== --- src/utils.c (revision 5036) +++ src/utils.c (working copy) @@ -458,12 +458,28 @@ return src; } +static size_t edit_pg_start=0; + +inline size_t get_edit_pg_start() {return edit_pg_start;} +inline void set_edit_pg_start(size_t column) {edit_pg_start = column;} + /* nano scrolls horizontally within a line in chunks. Return the column * number of the first character displayed in the edit window when the * cursor is at the given column. Note that (0 <= column - * get_page_start(column) < COLS). */ size_t get_page_start(size_t column) { + if (ISSET(SMOOTH_HORZ_SCROLL)) { + if (column <= 0) + return 0; + else if (column <= edit_pg_start) + return column-1; + else if ((column - edit_pg_start) > COLS-2 ) + return column - (COLS - 2); + else + return edit_pg_start; + } + else { if (column == 0 || column < COLS - 1) return 0; else if (COLS > 8) @@ -471,6 +487,7 @@ else return column - (COLS - 2); } +} /* Return the placewewant associated with current_x, i.e. the zero-based * column position of the cursor. The value will be no smaller than Index: src/winio.c =================================================================== --- src/winio.c (revision 5036) +++ src/winio.c (working copy) @@ -2873,6 +2873,21 @@ #endif /* !NANO_TINY */ } +void update_page(void) +{ + size_t curr_col =xplustabs(); + + size_t pg_start = get_page_start(curr_col); + size_t old_pg_start = EDITWIN_CURR_PG_START; + + if (pg_start != old_pg_start) { + set_edit_pg_start(pg_start); + edit_refresh(); + } + else + update_line(openfile->current, pg_start); +} + /* Just update one line in the edit buffer. This is basically a wrapper * for edit_draw(). The line will be displayed starting with * fileptr->data[index]. Likely arguments are current_x or zero. @@ -2885,7 +2900,7 @@ char *converted; /* fileptr->data converted to have tabs and control characters * expanded. */ - size_t page_start; + size_t page_start = 0; assert(fileptr != NULL); @@ -2912,9 +2927,13 @@ index = 0; else #endif + if (ISSET(SMOOTH_HORZ_SCROLL)) { + index = EDITWIN_CURR_PG_START; + page_start = index; + } else { index = strnlenpt(fileptr->data, index); page_start = get_page_start(index); - + } /* Expand the line, replacing tabs with spaces, and control * characters with their displayed forms. */ #ifdef NANO_TINY @@ -3125,10 +3144,10 @@ if ((i == nlines && direction == DOWNWARD) || (i == 1 && direction == UPWARD)) { if (do_redraw) - update_line(foo, (foo == openfile->current) ? + update_line(foo, (foo == openfile->current || ISSET(SMOOTH_HORZ_SCROLL)) ? openfile->current_x : 0); } else - update_line(foo, (foo == openfile->current) ? + update_line(foo, (foo == openfile->current || ISSET(SMOOTH_HORZ_SCROLL)) ? openfile->current_x : 0); foo = foo->next; } @@ -3139,17 +3158,27 @@ * updated. Use this if we've moved without changing any text. */ void edit_redraw(filestruct *old_current, size_t pww_save) { + bool bScrollRequired = (old_current->lineno < openfile->edittop->lineno || + old_current->lineno >= openfile->edittop->lineno + + maxrows || openfile->current->lineno < + openfile->edittop->lineno || openfile->current->lineno >= + openfile->edittop->lineno + maxrows); + + if (ISSET(SMOOTH_HORZ_SCROLL)) { + + if (bScrollRequired) + edit_update(CENTER); + + return update_page(); + } + bool do_redraw = need_vertical_update(0) || need_vertical_update(pww_save); filestruct *foo = NULL; /* If either old_current or current is offscreen, scroll the edit * window until it's onscreen and get out. */ - if (old_current->lineno < openfile->edittop->lineno || - old_current->lineno >= openfile->edittop->lineno + - maxrows || openfile->current->lineno < - openfile->edittop->lineno || openfile->current->lineno >= - openfile->edittop->lineno + maxrows) { + if (bScrollRequired) { #ifdef DEBUG fprintf(stderr, "edit_redraw(): line %ld was offscreen, oldcurrent = %ld edittop = %ld", (long)openfile->current->lineno, (long)old_current->lineno, (long)openfile->edittop->lineno);