From: Michael D. Lowis Date: Wed, 16 Nov 2016 22:53:12 +0000 (-0500) Subject: updated view to only sync to the cursor location when it moves. This will allow scrol... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=a86a4657d2deba66cd86e8f6476b8d6b8250fe88;p=projs%2Ftide.git updated view to only sync to the cursor location when it moves. This will allow scrolling without moving the cursor or selection --- diff --git a/Welcome.md b/Welcome.md new file mode 100644 index 0000000..25eba9d --- /dev/null +++ b/Welcome.md @@ -0,0 +1,5 @@ +# Mouse Shortcuts + +# Keyboard Shortcuts + +# Tag Commands diff --git a/inc/edit.h b/inc/edit.h index da2bf33..bd4b3da 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -137,20 +137,16 @@ typedef struct { } Row; typedef struct { - //size_t posx; - //size_t posy; - //size_t height; - //size_t width; - size_t nrows; /* number of rows in the view */ - size_t ncols; /* number of columns in the view */ - Row** rows; /* array of row data structures */ - Buf buffer; /* the buffer used to populate the view */ - Sel selection; /* range of currently selected text */ + bool sync_needed; /* determines whether the view needs to be synced with cursor */ + size_t nrows; /* number of rows in the view */ + size_t ncols; /* number of columns in the view */ + Row** rows; /* array of row data structures */ + Buf buffer; /* the buffer used to populate the view */ + Sel selection; /* range of currently selected text */ } View; void view_init(View* view, char* file); void view_resize(View* view, size_t nrows, size_t ncols); -//void view_resize(View* view, size_t x, size_t y, size_t height, size_t width, size_t fheight, size_t fwidth); void view_update(View* view, size_t* csrx, size_t* csry); Row* view_getrow(View* view, size_t row); void view_byrune(View* view, int move); @@ -165,15 +161,6 @@ void view_insert(View* view, Rune rune); //size_t view_setcell(View* view, size_t row, size_t col, uint32_t attr, Rune r); //UGlyph* view_getglyph(View* view, size_t row, size_t col, size_t* scrwidth); -void screen_update(Buf* buf, unsigned crsr, unsigned* csrx, unsigned* csry); -unsigned screen_getoff(Buf* buf, unsigned pos, unsigned row, unsigned col); -void screen_setsize(Buf* buf, unsigned nrows, unsigned ncols); -void screen_getsize(unsigned* nrows, unsigned* ncols); -Row* screen_getrow(unsigned row); -void screen_clearrow(unsigned row); -unsigned screen_setcell(unsigned row, unsigned col, uint32_t attr, Rune r); -UGlyph* screen_getglyph(unsigned row, unsigned col, unsigned* scrwidth); - /* Command Executions *****************************************************************************/ typedef struct { diff --git a/libedit/screen.c b/libedit/screen.c deleted file mode 100644 index cd1c3ae..0000000 --- a/libedit/screen.c +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include - -static unsigned NumRows = 0; -static unsigned NumCols = 0; -static Row** Rows; - -#define ATTR_NORMAL (CLR_BASE03 << 8 | CLR_BASE0) -#define ATTR_SELECTED (CLR_BASE0 << 8 | CLR_BASE03) - -static unsigned fill_row(Buf* buf, unsigned row, unsigned pos) { - screen_getrow(row)->off = pos; - screen_clearrow(row); - for (unsigned x = 0; x < NumCols;) { - uint32_t attr = (SelBeg <= pos && pos < SelEnd ? ATTR_SELECTED : ATTR_NORMAL); - Rune r = buf_get(buf, pos++); - x += screen_setcell(row, x, attr, r); - if (buf_iseol(buf, pos-1)) break; - } - return pos; -} - -static void screen_reflow(Buf* buf) { - unsigned pos = Rows[0]->off; - for (unsigned y = 0; y < NumRows; y++) - pos = fill_row(buf, y, pos); -} - -void screen_setsize(Buf* buf, unsigned nrows, unsigned ncols) { - if (NumRows == nrows && NumCols == ncols) return; - /* free the old row data */ - if (Rows) { - for (unsigned i = 0; i < NumRows; i++) - free(Rows[i]); - free(Rows); - } - /* create the new row data */ - Rows = calloc(nrows, sizeof(Row*)); - for (unsigned i = 0; i < nrows; i++) - Rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(UGlyph))); - /* update dimensions */ - NumRows = nrows; - NumCols = ncols; - /* populate the screen buffer */ - screen_reflow(buf); -} - -unsigned screen_getoff(Buf* buf, unsigned pos, unsigned row, unsigned col) { - Row* scrrow = screen_getrow(row); - if (!scrrow) return pos; - pos = scrrow->off; - if (col > scrrow->len) { - pos = (scrrow->off + scrrow->rlen - 1); - } else { - /* multi column runes are followed by \0 slots so if we clicked on a \0 - slot, slide backwards to the real rune. */ - for (; !scrrow->cols[col].rune && col > 0; col--); - /* now lets count the number of runes up to the one we clicked on */ - for (unsigned i = 0; i < col; i++) - if (scrrow->cols[i].rune) - pos++; - } - if (pos >= buf_end(buf)) - return buf_end(buf)-1; - return pos; -} - -void screen_getsize(unsigned* nrows, unsigned* ncols) { - *nrows = NumRows, *ncols = NumCols; -} - -Row* screen_getrow(unsigned row) { - return (row < NumRows ? Rows[row] : NULL); -} - -void screen_clearrow(unsigned row) { - Row* scrrow = screen_getrow(row); - if (!scrrow) return; - for (unsigned i = 0; i < NumCols; i++) - scrrow->cols[i].rune = (Rune)' '; - scrrow->rlen = 0; - scrrow->len = 0; -} - -unsigned screen_setcell(unsigned row, unsigned col, uint32_t attr, Rune r) { - if (row >= NumRows || col >= NumCols) return 0; - Row* scrrow = screen_getrow(row); - int ncols = runewidth(col, r); - /* write the rune to the screen buf */ - scrrow->cols[col].attr = attr; - if (r == '\t' || r == '\n' || r == RUNE_CRLF) - scrrow->cols[col].rune = ' '; - else - scrrow->cols[col].rune = r; - /* Update lengths */ - scrrow->rlen += 1; - for (int i = 1; i < ncols; i++) { - scrrow->cols[col].attr = attr; - scrrow->cols[col+i].rune = '\0'; - } - if ((col + ncols) > scrrow->len) - scrrow->len = col + ncols; - return ncols; -} - -UGlyph* screen_getglyph(unsigned row, unsigned col, unsigned* scrwidth) { - if (row >= NumRows || col >= NumCols) return 0; - Row* scrrow = screen_getrow(row); - UGlyph* glyph = &(scrrow->cols[col]); - *scrwidth = 1; - for (col++; !scrrow->cols[col].rune; col++) - *scrwidth += 1; - return glyph; -} - -static unsigned prev_screen_line(Buf* buf, unsigned bol, unsigned off) { - unsigned pos = bol; - while (true) { - unsigned x; - for (x = 0; x < NumCols && (pos + x) < off; x++) - x += runewidth(x, buf_get(buf, pos+x)); - if ((pos + x) >= off) break; - pos += x; - } - return pos; -} - -static void scroll_up(Buf* buf, unsigned csr, unsigned first) { - while (csr < first) { - unsigned bol = buf_bol(buf, first); - unsigned prevln = (first == bol ? buf_byline(buf, bol, -1) : bol); - prevln = prev_screen_line(buf, prevln, first); - /* delete the last row and shift the others */ - free(Rows[NumRows - 1]); - memmove(&Rows[1], &Rows[0], sizeof(Row*) * (NumRows-1)); - Rows[0] = calloc(1, sizeof(Row) + (NumCols * sizeof(UGlyph))); - Rows[0]->off = prevln; - /* fill in row content */ - fill_row(buf, 0, Rows[0]->off); - first = Rows[0]->off; - } -} - -static void scroll_dn(Buf* buf, unsigned csr, unsigned last) { - while (csr > last) { - /* delete the first row and shift the others */ - free(Rows[0]); - memmove(&Rows[0], &Rows[1], sizeof(Row*) * (NumRows-1)); - Rows[NumRows-1] = calloc(1, sizeof(Row) + (NumCols * sizeof(UGlyph))); - Rows[NumRows-1]->off = (Rows[NumRows-2]->off + Rows[NumRows-2]->rlen); - /* fill in row content */ - fill_row(buf, NumRows-1, Rows[NumRows-1]->off); - last = Rows[NumRows-1]->off + Rows[NumRows-1]->rlen - 1; - } -} - -static void sync_view(Buf* buf, unsigned csr) { - unsigned first = Rows[0]->off; - unsigned last = Rows[NumRows-1]->off + Rows[NumRows-1]->rlen - 1; - if (csr < first) { - scroll_up(buf, csr, first); - } else if (csr > last) { - scroll_dn(buf, csr, last); - } -} - -void screen_update(Buf* buf, unsigned csr, unsigned* csrx, unsigned* csry) { - /* scroll the view and reflow the screen lines */ - sync_view(buf, csr); - screen_reflow(buf); - /* find the cursor on the new screen */ - for (unsigned y = 0; y < NumRows; y++) { - unsigned start = Rows[y]->off; - unsigned end = Rows[y]->off + Rows[y]->rlen - 1; - if (start <= csr && csr <= end) { - unsigned pos = start; - for (unsigned x = 0; x < NumCols;) { - if (pos == csr) { - *csry = y, *csrx = x; - break; - } - x += runewidth(x, buf_get(buf,pos++)); - } - break; - } - } -} diff --git a/libedit/view.c b/libedit/view.c index 3b5f8ff..29917aa 100644 --- a/libedit/view.c +++ b/libedit/view.c @@ -121,6 +121,7 @@ static void sync_view(View* view, size_t csr) { } else if (csr > last) { scroll_dn(view, csr, last); } + view->sync_needed = false; } static size_t getoffset(View* view, size_t row, size_t col) { @@ -168,16 +169,14 @@ void view_resize(View* view, size_t nrows, size_t ncols) { view->rows[0]->off = off; view->nrows = nrows; view->ncols = ncols; - /* populate the screen buffer */ - reflow(view); - sync_view(view, view->selection.end); } void view_update(View* view, size_t* csrx, size_t* csry) { size_t csr = view->selection.end; /* scroll the view and reflow the screen lines */ - sync_view(view, view->selection.end); reflow(view); + if (view->sync_needed) + sync_view(view, csr); /* find the cursor on the new screen */ for (size_t y = 0; y < view->nrows; y++) { size_t start = view->rows[y]->off; @@ -205,7 +204,7 @@ void view_byrune(View* view, int move) { sel.beg = sel.end = buf_byrune(&(view->buffer), sel.end, move); sel.col = buf_getcol(&(view->buffer), sel.end); view->selection = sel; - sync_view(view, view->selection.end); + view->sync_needed = true; } void view_byline(View* view, int move) { @@ -213,7 +212,7 @@ void view_byline(View* view, int move) { sel.beg = sel.end = buf_byline(&(view->buffer), sel.end, move); sel.beg = sel.end = buf_setcol(&(view->buffer), sel.end, sel.col); view->selection = sel; - sync_view(view, view->selection.end); + view->sync_needed = true; } void view_setcursor(View* view, size_t row, size_t col) { @@ -242,7 +241,7 @@ void view_insert(View* view, Rune rune) { } view->selection.beg = view->selection.end; view->selection.col = buf_getcol(&(view->buffer), view->selection.end); - sync_view(view, view->selection.end); + view->sync_needed = true; } void view_delete(View* view) { @@ -252,4 +251,5 @@ void view_delete(View* view) { // buf_del(&Buffer, SelBeg); //SelEnd = SelBeg; //TargetCol = buf_getcol(&Buffer, SelEnd); + //view->sync_needed = true; } diff --git a/xedit b/xedit new file mode 100755 index 0000000..f2aab65 Binary files /dev/null and b/xedit differ