typedef size_t (*movefn_t)(Buf* buf, size_t pos, int count);
-static void move_selection(View* view, bool extsel, int move, movefn_t bything);
-static void move_to(View* view, bool extsel, size_t off);
-static bool selection_visible(View* view);
-static void find_cursor(View* view, size_t* csrx, size_t* csry);
-static void clearrow(View* view, size_t row);
-static size_t setcell(View* view, size_t row, size_t col, Rune r);
-static size_t fill_row(View* view, unsigned row, size_t pos);
-static unsigned prev_screen_line(View* view, unsigned bol, unsigned off);
-static unsigned scroll_up(View* view);
-static unsigned scroll_dn(View* view);
-static void sync_center(View* view, size_t csr);
-static size_t getoffset(View* view, size_t row, size_t col);
+static void move_selection(View* view, bool extsel, int move, movefn_t bything) {
+ view->sync_flags |= CURSOR;
+ if (buf_selsz(BUF) && !extsel) {
+ buf_selclr(BUF, move);
+ } else {
+ CSRPOS = bything(BUF, CSRPOS, move);
+ if (bything == buf_byline)
+ buf_setcol(BUF);
+ if (!extsel)
+ buf_selclr(BUF, RIGHT);
+ }
+ /* only update column if not moving vertically */
+ if (bything != buf_byline)
+ buf_getcol(BUF);
+}
+
+static void move_to(View* view, bool extsel, size_t off) {
+ Buf* buf = BUF;
+ CSRPOS = (off > buf_end(buf) ? buf_end(buf) : off);
+ if (!extsel)
+ buf_selclr(BUF, RIGHT);
+ buf_getcol(buf);
+ view->sync_flags |= CURSOR;
+}
+
+static bool selection_visible(View* view) {
+ if (!view->nrows) return true;
+ size_t csr = CSRPOS;
+ size_t beg = view->rows[0]->off;
+ size_t end = view->rows[view->nrows-1]->off +
+ view->rows[view->nrows-1]->len;
+ return (beg <= csr && csr <= end);
+}
+
+static void find_cursor(View* view, size_t* csrx, size_t* csry) {
+ size_t csr = CSRPOS;
+ for (size_t y = 0; y < view->nrows; y++) {
+ size_t start = view->rows[y]->off;
+ size_t end = view->rows[y]->off + view->rows[y]->len - 1;
+ if (start <= csr && csr <= end) {
+ size_t pos = start;
+ break;
+ }
+ }
+}
static Sel* getsel(View* view) {
return &(view->buffer.selection);
}
size_t view_limitrows(View* view, size_t maxrows, size_t ncols) {
- size_t nrows = 1, pos = 0, col = 0;
- while (nrows < maxrows && pos < buf_end(BUF)) {
- Rune r = buf_getrat(BUF, pos++);
- col += runewidth(col, r);
- if (col >= ncols || r == '\n')
- col = 0, nrows++;
- }
- return nrows;
+ return 1;
}
-void view_resize(View* view, size_t nrows, size_t ncols) {
-#if 1
- size_t off = 0;
- if (view->nrows == nrows && view->ncols == ncols) return;
- /* free the old row data */
- if (view->nrows) {
- off = view->rows[0]->off;
- for (size_t i = 0; i < view->nrows; i++)
- free(view->rows[i]);
- free(view->rows);
- }
- /* create the new row data */
- view->rows = calloc(nrows, sizeof(Row*));
- for (unsigned i = 0; i < nrows; i++)
- view->rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(UGlyph)));
- /* update dimensions */
- view->rows[0]->off = off;
- view->nrows = nrows;
- view->ncols = ncols;
-#endif
-}
-
-void view_update(View* view, int clrnor, int clrsel, size_t* csrx, size_t* csry) {
-#if 1
- if (!view->nrows) return;
- size_t csr = CSRPOS;
- /* scroll the view and reflow the screen lines */
- size_t pos = view->rows[0]->off;
- /* fill the view and scroll if needed */
- for (size_t y = 0; y < view->nrows; y++)
- pos = fill_row(view, y, pos);
- if (view->sync_flags)
- view_scrollto(view, csr);
- /* locate the cursor if visible */
- find_cursor(view, csrx, csry);
-#endif
+void view_resize(View* view, size_t width, size_t nrows) {
+}
+
+void view_update(View* view, size_t* csrx, size_t* csry) {
}
Row* view_getrow(View* view, size_t row) {
}
void view_setcursor(View* view, size_t row, size_t col, bool extsel) {
- size_t off = getoffset(view, row, col);
- if (off != SIZE_MAX)
- view_jumpto(view, extsel, off);
}
void view_selword(View* view, size_t row, size_t col) {
}
char* view_fetch(View* view, size_t row, size_t col, bool (*isword)(Rune)) {
- char* str = NULL;
- size_t off = getoffset(view, row, col);
- if (off != SIZE_MAX)
- str = buf_fetch(BUF, isword, off);
+ char* str = NULL;
+// size_t off = getoffset(view, row, col);
+// if (off != SIZE_MAX)
+// str = buf_fetch(BUF, isword, off);
return str;
}
int dir = (move < 0 ? -1 : 1);
move *= dir;
for (int i = 0; i < move; i++) {
- if (dir < 0)
- scroll_up(view);
- else
- scroll_dn(view);
+// if (dir < 0)
+// scroll_up(view);
+// else
+// scroll_dn(view);
}
}
}
void view_scrollto(View* view, size_t csr) {
- if (!view->nrows) return;
- unsigned first = view->rows[0]->off;
- unsigned last = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen - 1;
- while (csr < first)
- first = scroll_up(view);
- while (csr > last && last < buf_end(BUF))
- last = scroll_dn(view);
- if (view->sync_flags & CENTER)
- sync_center(view, csr);
- view->sync_flags = 0;
}
void view_selectall(View* view) {
view->sync_flags |= CURSOR;
}
-static void move_selection(View* view, bool extsel, int move, movefn_t bything) {
- view->sync_flags |= CURSOR;
- if (buf_selsz(BUF) && !extsel) {
- buf_selclr(BUF, move);
- } else {
- CSRPOS = bything(BUF, CSRPOS, move);
- if (bything == buf_byline)
- buf_setcol(BUF);
- if (!extsel)
- buf_selclr(BUF, RIGHT);
- }
- /* only update column if not moving vertically */
- if (bything != buf_byline)
- buf_getcol(BUF);
-}
-
-static void move_to(View* view, bool extsel, size_t off) {
- Buf* buf = BUF;
- CSRPOS = (off > buf_end(buf) ? buf_end(buf) : off);
- if (!extsel)
- buf_selclr(BUF, RIGHT);
- buf_getcol(buf);
- view->sync_flags |= CURSOR;
-}
-
-static bool selection_visible(View* view) {
- if (!view->nrows) return true;
- size_t csr = CSRPOS;
- size_t beg = view->rows[0]->off;
- size_t end = view->rows[view->nrows-1]->off +
- view->rows[view->nrows-1]->rlen;
- return (beg <= csr && csr <= end);
-}
-static void find_cursor(View* view, size_t* csrx, size_t* csry) {
- size_t csr = CSRPOS;
- for (size_t y = 0; y < view->nrows; y++) {
- size_t start = view->rows[y]->off;
- size_t end = view->rows[y]->off + view->rows[y]->rlen - 1;
- if (start <= csr && csr <= end) {
- size_t pos = start;
- for (size_t x = 0; x < view->ncols;) {
- if (pos == csr) {
- *csry = y, *csrx = x;
- break;
- }
- x += runewidth(x, buf_getrat(BUF, pos++));
- }
- break;
- }
- }
-}
-
-static void clearrow(View* view, size_t row) {
- Row* scrrow = view_getrow(view, row);
- if (!scrrow) return;
- for (size_t i = 0; i < view->ncols; i++)
- scrrow->cols[i].rune = (Rune)' ';
- scrrow->rlen = 0;
- scrrow->len = 0;
-}
-
-static size_t setcell(View* view, size_t row, size_t col, Rune r) {
- if (row >= view->nrows || col >= view->ncols) return 0;
- Row* scrrow = view_getrow(view, row);
- int ncols = runewidth(col, r);
- /* write the rune to the screen buf */
- if (r == '\t')
- 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+i].rune = '\0';
- }
- if ((col + ncols) > scrrow->len)
- scrrow->len = col + ncols;
- return ncols;
-}
-
-static size_t fill_row(View* view, unsigned row, size_t pos) {
- view_getrow(view, row)->off = pos;
- clearrow(view, row);
- for (size_t x = 0; x < view->ncols;) {
- Rune r = buf_getrat(BUF, pos++);
- x += setcell(view, row, x, r);
- if (buf_iseol(BUF, pos-1)) {
- break;
- }
- }
- return pos;
-}
-
-static unsigned prev_screen_line(View* view, unsigned bol, unsigned off) {
- unsigned pos = bol;
- while (true) {
- unsigned x;
- for (x = 0; x < view->ncols && (pos + x) < off; x++)
- x += runewidth(x, buf_getrat(BUF, pos+x));
- if ((pos + x) >= off) break;
- pos += x;
- }
- return pos;
-}
-
-static unsigned scroll_up(View* view) {
- size_t first = view->rows[0]->off;
- size_t bol = buf_bol(BUF, first);
- size_t prevln = (first == bol ? buf_byline(BUF, bol, UP) : bol);
- if (!first) return first;
- prevln = prev_screen_line(view, prevln, first);
- /* delete the last row and shift the others */
- free(view->rows[view->nrows - 1]);
- memmove(&view->rows[1], &view->rows[0], sizeof(Row*) * (view->nrows-1));
- view->rows[0] = calloc(1, sizeof(Row) + (view->ncols * sizeof(UGlyph)));
- view->rows[0]->off = prevln;
- /* fill in row content */
- fill_row(view, 0, view->rows[0]->off);
- return view->rows[0]->off;
-}
-
-static unsigned scroll_dn(View* view) {
- size_t last = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen - 1;
- if (last >= buf_end(BUF)) return last;
- /* delete the first row and shift the others */
- if (view->nrows > 1) {
- free(view->rows[0]);
- memmove(&view->rows[0], &view->rows[1], sizeof(Row*) * (view->nrows-1));
- view->rows[view->nrows-1] = calloc(1, sizeof(Row) + (view->ncols * sizeof(UGlyph)));
- view->rows[view->nrows-1]->off = (view->rows[view->nrows-2]->off + view->rows[view->nrows-2]->rlen);
- /* fill in row content */
- fill_row(view, view->nrows-1, view->rows[view->nrows-1]->off);
- } else {
- view->rows[0]->off += view->rows[0]->rlen;
- fill_row(view, 0, view->rows[0]->off);
- }
- return view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen - 1;
-}
-
-static void sync_center(View* view, size_t csr) {
- /* determine the screenline containing the cursor */
- size_t scrln = 0;
- for (; scrln < view->nrows; scrln++) {
- unsigned first = view->rows[scrln]->off;
- unsigned last = first + view->rows[scrln]->rlen - 1;
- if (csr >= first && csr <= last)
- break;
- }
- /* find the middle row and scroll until the cursor is on that row */
- unsigned midrow = view->nrows / 2;
- int move = (scrln - midrow);
- unsigned count = (move < 0 ? -move : move);
- for (; count > 0; count--)
- (move < 0 ? scroll_up : scroll_dn)(view);
-}
-
-static size_t getoffset(View* view, size_t row, size_t col) {
- Row* scrrow = view_getrow(view, row);
- if (!scrrow) return SIZE_MAX;
- size_t 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);
- return pos;
-}
XftColorFree(X.display, X.visual, X.colormap, &fgc);
}
-static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t ncols) {
+static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t len) {
+#if 0
XGlyphSpec specs[rlen];
size_t i = 0;
bool eol = false;
place_glyphs(EditFg, specs, numspecs, eol);
eol = false, rlen -= numspecs;
}
+#endif
}
static void draw_view(int i, size_t nrows, drawcsr* csr, int bg, int fg, int sel) {
size_t csrx = SIZE_MAX, csry = SIZE_MAX;
/* draw the view to the window */
View* view = win_view(i);
- view_resize(view, nrows, (csr->w - csr->x) / fwidth);
- view_update(view, (bg << 8 | fg), (sel << 8 | fg), &csrx, &csry);
+ view_resize(view, (csr->w - csr->x), nrows);
+ view_update(view, &csrx, &csry);
draw_rect(bg, csr->x, csr->y, csr->w, (nrows * fheight) + 9);
for (size_t y = 0; y < view->nrows; y++) {
Row* row = view_getrow(view, y);
- draw_glyphs(csr->x + 2, csr->y + 2 + ((y+1) * fheight), row->cols, row->rlen, row->len);
+ draw_glyphs(csr->x + 2, csr->y + 2 + ((y+1) * fheight), row->cols, row->len);
}
/* place the cursor on screen */
if (!view_selsize(view) && csrx != SIZE_MAX && csry != SIZE_MAX) {
if (bend == 0) bend = 1;
if (!view->rows) return;
size_t vbeg = view->rows[0]->off;
- size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen;
+ size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->len;
double scroll_vis = (double)(vend - vbeg) / (double)bend;
double scroll_off = ((double)vbeg / (double)bend);
size_t thumbreg = (csr->y - Divider) + 4;
drawcsr csr = { .w = X.width, .h = X.height };
size_t maxtagrows = ((X.height - 2) / 4) / fheight;
size_t tagcols = csr.w / fwidth;
- size_t tagrows = view_limitrows(win_view(TAGS), maxtagrows, tagcols);
+ size_t tagrows = 1;
size_t editrows = ((X.height - 7) / fheight) - tagrows;
/* draw the regions to the window */
draw_view(TAGS, tagrows, &csr, TagsBg, TagsFg, TagsSel);