From d8510b2732a080b553bf2951d9bb6c1795f47ec2 Mon Sep 17 00:00:00 2001 From: Robert Siemborski Date: Tue, 6 Jun 2000 23:04:06 +0000 Subject: [PATCH] Substantial changes to winio.c that appear to fix the display problems that we have been seeing on lines with tabs. It introduces the concept of "pages" which might not be the best choice for them.... Basically, it's the part of a line that would be visible on screen at once. the first part (visible when you open a file) is page 1... the second (you have to scroll to the right approx COLS, is 2. The third is at approx (2 * COLS) - 7 and so on...) It's not terribly efficient as of yet, there are probabally quite a few redundant calls to xpt(), for instance. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@6 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- winio.c | 253 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 155 insertions(+), 98 deletions(-) diff --git a/winio.c b/winio.c index 3cb92f84..bbf6d5a1 100644 --- a/winio.c +++ b/winio.c @@ -34,6 +34,12 @@ static int statblank = 0; /* Number of keystrokes left after we call statubar() before we actually blank the statusbar */ + +/* Local Function Prototypes for only winio.c */ +inline int get_page_from_virtual(int virtual); +inline int get_page_start_virtual(int page); +inline int get_page_end_virtual(int page); + /* Window I/O */ int do_first_line(void) @@ -88,34 +94,34 @@ int xplustabs(void) } -/* Return what current_x should be, given xplustabs() for the line. - Opposite of xplustabs */ -int actual_x(filestruct * fileptr, int xplus) +/* Return what current_x should be, given xplustabs() for the line, + * given a start position in the filestruct's data */ +int actual_x_from_start(filestruct * fileptr, int xplus, int start) { - int i, tot = 0; + int i, tot = 1; if (fileptr == NULL || fileptr->data == NULL) return 0; - for (i = 1; i + tot <= xplus && fileptr->data[i - 1] != 0; i++) - if (fileptr->data[i - 1] == NANO_CONTROL_I) { - if ((i + tot) % 8 == 0) - tot++; - else - tot += 8 - ((i + tot) % 8); - } else if (fileptr->data[i - 1] & 0x80) - tot ++; /* Make 8 bit chars only 1 column (again) */ - else if (fileptr->data[i - 1] < 32) + for (i = start; tot <= xplus && fileptr->data[i] != 0; i++,tot++) + if (fileptr->data[i] == NANO_CONTROL_I) { + if (tot % 8 == 0) tot++; + else tot += 8 - (tot % 8); + } else if (fileptr->data[i] & 0x80) + tot++; /* Make 8 bit chars only 1 column (again) */ + else if (fileptr->data[i] < 32) tot += 2; - if (fileptr->data[i - 1] != 0) - i--; /* Im sure there's a good reason why this is needed for - it to work, I just cant figure out why =-) */ - #ifdef DEBUG fprintf(stderr, _("actual_x for xplus=%d returned %d\n"), xplus, i); #endif - return i; + return i - start; +} + +/* Opposite of xplustabs */ +inline int actual_x(filestruct * fileptr, int xplus) +{ + return actual_x_from_start(fileptr, xplus, 0); } /* a strlen with tabs factored in, similar to xplustabs() */ @@ -160,9 +166,10 @@ void reset_cursor(void) x = xplustabs(); if (x <= COLS - 2) - wmove(edit, current_y, x % (COLS - 1)); + wmove(edit, current_y, x); else - wmove(edit, current_y, x % (COLS - 7) + 1); + wmove(edit, current_y, x - + get_page_start_virtual(get_page_from_virtual(xplustabs()))); } @@ -517,43 +524,93 @@ void set_modified(void) } } -#ifndef NANO_SMALL -void add_marked_sameline(int begin, int end, filestruct * fileptr, int y) -{ - int col, actual_col = 0, begin_mapped = 0, end_mapped = 0; +inline int get_page_from_virtual(int virtual) { + int page = 2; - if (current_x > COLS - 2) { - col = (COLS - 7) * (xplustabs() / (COLS - 7)) - 1; - actual_col = actual_x(fileptr, col); - begin_mapped = begin % (COLS - 7) + 1; - end_mapped = end % (COLS - 7) + 1; - } else { - actual_col = 0; - begin_mapped = begin; - end_mapped = end; + if(virtual <= COLS - 2) return 1; + virtual -= (COLS - 2); + + while (virtual > COLS - 2 - 7) { + virtual -= (COLS - 2 - 7); + page++; } - if (end > (COLS - 2) && ((begin / (COLS - 7)) != (end / (COLS - 7)))) { - if (current_x == begin) { - mvwaddnstr(edit, y, 0, &fileptr->data[actual_col], - begin_mapped); - wattron(edit, A_REVERSE); - waddnstr(edit, &fileptr->data[begin], COLS - begin_mapped); - wattroff(edit, A_REVERSE); - } else { - wattron(edit, A_REVERSE); - mvwaddnstr(edit, y, 0, &fileptr->data[actual_col], end_mapped); - wattroff(edit, A_REVERSE); - waddnstr(edit, &fileptr->data[end], COLS - end_mapped); - } - } else { - mvwaddnstr(edit, y, 0, &fileptr->data[actual_col], begin_mapped); - wattron(edit, A_REVERSE); - waddnstr(edit, &fileptr->data[begin], end_mapped - begin_mapped); - wattroff(edit, A_REVERSE); - waddnstr(edit, &fileptr->data[end], - COLS - (end_mapped - begin_mapped)); + return page; +} + +inline int get_page_start_virtual(int page) { + int virtual; + virtual = --page * (COLS - 7); + if(page) virtual -= 2 * page - 1; + return virtual; +} + +inline int get_page_end_virtual(int page) { + return get_page_start_virtual(page) + COLS - 1; +} + +#ifndef NANO_SMALL +/* begin, end: beginning and end of mark in data + * fileptr: the data + * y: the line on screen */ +void add_marked_sameline(int begin, int end, filestruct *fileptr, int y) +{ + /* where we are on the line */ + int virtual_col = xplustabs(); + + /* actual_col is beginning of the line in the data */ + int this_page = get_page_from_virtual(virtual_col), + this_page_start = get_page_start_virtual(this_page), + this_page_end = get_page_end_virtual(this_page), + actual_col = actual_x(fileptr, this_page_start); + + /* 3 start points: 0 -> begin, begin->end, end->strlen(data) */ + /* in data : pre sel post */ + int virtual_sel_start = xpt(fileptr, begin), + sel_start = 0, + virtual_post_start = xpt(fileptr, end), + post_start = 0; + + /* likewise, 3 data lengths */ + int pre_data_len = begin, + sel_data_len = end - begin, + post_data_len = 0; + + /* now fix the start locations & lengths according to the cursor's + * position (ie: our page) */ + if(xpt(fileptr,pre_data_len) < this_page_start) pre_data_len = 0; + else pre_data_len -= actual_col; + + if(virtual_sel_start < this_page_start) { + begin = actual_col; + virtual_sel_start = this_page_start; + } + if(virtual_post_start < this_page_start) { + end = actual_col; + virtual_post_start = this_page_start; } + + /* we don't care about end, because it will just get cropped + * due to length */ + if(virtual_sel_start > this_page_end) + virtual_sel_start = this_page_end; + if(virtual_post_start > this_page_end) + virtual_post_start = this_page_end; + + sel_data_len = actual_x(fileptr, virtual_post_start) - + actual_x(fileptr, virtual_sel_start); + + post_data_len = actual_x(fileptr, this_page_end) - + actual_x(fileptr, virtual_post_start); + + sel_start = virtual_sel_start - this_page_start; + post_start = virtual_post_start - this_page_start; + + mvwaddnstr(edit, y, 0, &fileptr->data[actual_col], pre_data_len); + wattron(edit, A_REVERSE); + mvwaddnstr(edit, y, sel_start, &fileptr->data[begin], sel_data_len); + wattroff(edit, A_REVERSE); + mvwaddnstr(edit, y, post_start, &fileptr->data[end], post_data_len); } #endif @@ -563,69 +620,70 @@ void edit_add(filestruct * fileptr, int yval, int xval, int start) int col; if (ISSET(MARK_ISSET)) { - - /* Our horribly ugly marker code, which needs to be rewritten too :P */ + /* Our horribly ugly marker code */ if ((fileptr->lineno > mark_beginbuf->lineno && fileptr->lineno > current->lineno) || (fileptr->lineno < mark_beginbuf->lineno && fileptr->lineno < current->lineno)) { /* We're on a normal, unselected line */ - mvwaddnstr(edit, yval, 0, fileptr->data, COLS); - - if (strlenpt(fileptr->data) > COLS) - mvwaddch(edit, yval, COLS - 1, '$'); + mvwaddnstr(edit, yval, 0, fileptr->data, + actual_x(fileptr, COLS)); } else { - /* We're on selected text */ if (fileptr != mark_beginbuf && fileptr != current) { wattron(edit, A_REVERSE); - mvwaddnstr(edit, yval, 0, fileptr->data, COLS); - if (strlenpt(fileptr->data) > COLS) - mvwaddch(edit, yval, COLS - 1, '$'); - + mvwaddnstr(edit, yval, 0, fileptr->data, actual_x(fileptr,COLS)); wattroff(edit, A_REVERSE); } /* Special case, we're still on the same line we started marking */ else if (fileptr == mark_beginbuf && fileptr == current) { - if (current_x < mark_beginx) { - add_marked_sameline(current_x, mark_beginx, fileptr, - yval); - } else { - add_marked_sameline(mark_beginx, current_x, fileptr, - yval); - } + if (current_x < mark_beginx) + add_marked_sameline(current_x, mark_beginx, fileptr, yval); + else + add_marked_sameline(mark_beginx, current_x, fileptr, yval); } else if (fileptr == mark_beginbuf) { + int target; + + /* we're at the line that was first marked */ if (mark_beginbuf->lineno > current->lineno) wattron(edit, A_REVERSE); - mvwaddnstr(edit, yval, 0, fileptr->data, mark_beginx); + target = (xpt(fileptr,mark_beginx) < COLS - 1) ? mark_beginx : COLS - 1; + + mvwaddnstr(edit, yval, 0, fileptr->data, + actual_x(fileptr, target)); if (mark_beginbuf->lineno < current->lineno) wattron(edit, A_REVERSE); else wattroff(edit, A_REVERSE); - waddnstr(edit, &fileptr->data[mark_beginx], - COLS - xpt(fileptr, mark_beginx)); + target = (COLS - 1) - xpt(fileptr,mark_beginx); + if(target < 0) target = 0; - if (strlenpt(fileptr->data) > COLS) - mvwaddch(edit, yval, COLS - 1, '$'); + mvwaddnstr(edit, yval, xpt(fileptr,mark_beginx), + &fileptr->data[mark_beginx], + actual_x_from_start(fileptr, target, mark_beginx)); if (mark_beginbuf->lineno < current->lineno) wattroff(edit, A_REVERSE); } else if (fileptr == current) { + /* we're on the cursors line, but it's not the first + * one we marked... */ + int this_page = get_page_from_virtual(xplustabs()), + this_page_start = get_page_start_virtual(this_page), + this_page_end = get_page_end_virtual(this_page); + if (mark_beginbuf->lineno < current->lineno) wattron(edit, A_REVERSE); - /* Thank GOD for waddnstr, this can now be much cleaner */ if (xplustabs() > COLS - 2) { - col = (COLS - 7) * (xplustabs() / (COLS - 7)); - mvwaddnstr(edit, yval, 1, - &fileptr->data[actual_x(current, col)], - current_x % (COLS - 7) + 1); + col = actual_x(current, this_page_start); + mvwaddnstr(edit, yval, 0, &fileptr->data[col], + current_x - col); } else mvwaddnstr(edit, yval, 0, fileptr->data, current_x); @@ -634,20 +692,15 @@ void edit_add(filestruct * fileptr, int yval, int xval, int start) else wattroff(edit, A_REVERSE); - if (xplustabs() > COLS - 2) { - mvwaddnstr(edit, yval, - xpt(current, - (current_x % (COLS - 7) + 1)), + mvwaddnstr(edit, yval, xplustabs() - this_page_start, &fileptr->data[current_x], - COLS - current_x); + actual_x(current,this_page_end) - current_x); } else mvwaddnstr(edit, yval, xplustabs(), &fileptr->data[current_x], - COLS - current_x); - - if (strlenpt(fileptr->data) > COLS) - mvwaddch(edit, yval, COLS - 1, '$'); + actual_x_from_start(fileptr, + COLS - xpt(fileptr,current_x), current_x)); if (mark_beginbuf->lineno > current->lineno) wattroff(edit, A_REVERSE); @@ -657,7 +710,8 @@ void edit_add(filestruct * fileptr, int yval, int xval, int start) } else #endif - mvwaddnstr(edit, yval, xval, &fileptr->data[start], COLS - xval); + mvwaddnstr(edit, yval, xval, &fileptr->data[start], + actual_x_from_start(fileptr,COLS - xval,start)); } @@ -667,6 +721,7 @@ void edit_add(filestruct * fileptr, int yval, int xval, int start) * index gives is a place in the string to update starting from. * Likely args are current_x or 0. */ + void update_line(filestruct * fileptr, int index) { filestruct *filetmp; @@ -679,19 +734,21 @@ void update_line(filestruct * fileptr, int index) mvwaddstr(edit, line, 0, hblank); if (current == fileptr && (x = xpt(current, index)) > COLS - 2) { - - col = (COLS - 7) * (x / (COLS - 7)); + int page = get_page_from_virtual(x); + col = get_page_start_virtual(page); actual_col = actual_x(filetmp, col); - edit_add(filetmp, line, 1, actual_col); + edit_add(filetmp, line, 0, actual_col); mvwaddch(edit, line, 0, '$'); - } else + if (strlenpt(fileptr->data) > get_page_end_virtual(page)) + mvwaddch(edit, line, COLS - 1, '$'); + } else { edit_add(filetmp, line, 0, 0); - if (strlenpt(&filetmp->data[actual_col]) > COLS) - mvwaddch(edit, line, COLS - 1, '$'); - + if (strlenpt(&filetmp->data[actual_col]) > COLS) + mvwaddch(edit, line, COLS - 1, '$'); + } } void center_cursor(void) -- 2.39.5