cursor movement fixes and comments
This commit is contained in:
parent
83e3b71cd4
commit
d5c7deef0e
108
ste.c
108
ste.c
@ -9,6 +9,7 @@
|
|||||||
#define TABSIZE 4 // Tab size as used in render
|
#define TABSIZE 4 // Tab size as used in render
|
||||||
#define STAT_SIZE 128
|
#define STAT_SIZE 128
|
||||||
#define _XOPEN_SOURCE_EXTENDED
|
#define _XOPEN_SOURCE_EXTENDED
|
||||||
|
#define EROW {0, NULL, 0, 0, NULL}
|
||||||
|
|
||||||
/* main data structure containing:
|
/* main data structure containing:
|
||||||
* -cursor position
|
* -cursor position
|
||||||
@ -39,11 +40,13 @@ struct term {
|
|||||||
/* Row structure, defines actual and
|
/* Row structure, defines actual and
|
||||||
* render chars, actual and render size
|
* render chars, actual and render size
|
||||||
* and difference between render and
|
* and difference between render and
|
||||||
* real size of the row */
|
* real size of the row
|
||||||
|
* Utf-8 continuation chars */
|
||||||
typedef struct row {
|
typedef struct row {
|
||||||
int size;
|
int size;
|
||||||
char *chars;
|
char *chars;
|
||||||
int r_size;
|
int r_size;
|
||||||
|
int utf;
|
||||||
char *render;
|
char *render;
|
||||||
} row;
|
} row;
|
||||||
|
|
||||||
@ -255,8 +258,8 @@ void drawScreen ()
|
|||||||
/* Draw all the appropriate lines (following cursor) to the screen */
|
/* Draw all the appropriate lines (following cursor) to the screen */
|
||||||
void drawLines (void)
|
void drawLines (void)
|
||||||
{
|
{
|
||||||
static int ln, i;
|
register int ln, i;
|
||||||
/* move to the beginning of the screen */
|
static int start;
|
||||||
|
|
||||||
for (i = 0, ln = 0; i < t.dim.y + t.cur.off_y; i++) {
|
for (i = 0, ln = 0; i < t.dim.y + t.cur.off_y; i++) {
|
||||||
ln = i + t.cur.off_y;
|
ln = i + t.cur.off_y;
|
||||||
@ -271,7 +274,9 @@ void drawLines (void)
|
|||||||
/* Draw the line matcing render memory */
|
/* Draw the line matcing render memory */
|
||||||
if (&rows.rw[ln] == NULL) termDie("drawlines NULL");
|
if (&rows.rw[ln] == NULL) termDie("drawlines NULL");
|
||||||
if (rows.rw[ln].r_size > t.cur.off_x) {
|
if (rows.rw[ln].r_size > t.cur.off_x) {
|
||||||
addnstr(&rows.rw[ln].render[t.cur.off_x], t.dim.x + 1); // good for utf-8
|
start = t.cur.off_x;
|
||||||
|
while (isCont(rows.rw[ln].render[start])) start++;
|
||||||
|
addnstr(&rows.rw[ln].render[start], t.dim.x + 1 + rows.rw[ln].utf / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
lnMove(i + 1, 0);
|
lnMove(i + 1, 0);
|
||||||
@ -311,10 +316,13 @@ void drawBar (char *s)
|
|||||||
|
|
||||||
void updateRender (row *rw)
|
void updateRender (row *rw)
|
||||||
{
|
{
|
||||||
/* count the special characters (only tabs for now) */
|
/* count the special characters
|
||||||
static int tabs = 0, i, off;
|
* spaces, utf-8 continuation chars */
|
||||||
for (i = 0, tabs = 0; i < rw->size; i++) {
|
static int tabs, i, off, cc, ut;
|
||||||
|
for (i = 0, tabs = 0, cc = 0, ut = 0; i < rw->size; i++) {
|
||||||
if (rw->chars[i] == '\t') tabs++;
|
if (rw->chars[i] == '\t') tabs++;
|
||||||
|
else if (isCont(rw->chars[i])) cc++;
|
||||||
|
else if (isUtf(rw->chars[i])) ut++;
|
||||||
}
|
}
|
||||||
rw->render = NULL;
|
rw->render = NULL;
|
||||||
free(rw->render);
|
free(rw->render);
|
||||||
@ -332,13 +340,14 @@ void updateRender (row *rw)
|
|||||||
//if (!j) rw->render[off++] = '|';
|
//if (!j) rw->render[off++] = '|';
|
||||||
//else rw->render[off++] = ' ';
|
//else rw->render[off++] = ' ';
|
||||||
rw->render[off++] = ' ';
|
rw->render[off++] = ' ';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rw->render[off++] = rw->chars[i];
|
rw->render[off++] = rw->chars[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rw->render[off] = '\0';
|
rw->render[off] = '\0';
|
||||||
rw->r_size = off;
|
rw->r_size = off - cc;
|
||||||
|
rw->utf = cc + ut;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------- draw operations -------------------------------- */
|
/* -------------------------------- draw operations -------------------------------- */
|
||||||
@ -465,62 +474,71 @@ void rowDeleteChar (row *rw, int select, int pos) // WIP
|
|||||||
|
|
||||||
void rowAddRow (int pos) // WIP; TO DOCUMENT
|
void rowAddRow (int pos) // WIP; TO DOCUMENT
|
||||||
{
|
{
|
||||||
char *s = NULL;
|
/* MOVE THE ROWS AWAY */
|
||||||
// Move away other lines
|
/* add another line to the bottom containing the previous
|
||||||
//copy old last line to new space
|
* (last) line, effectively making new space */
|
||||||
rowAddLast(rows.rw[rows.rownum - 1].chars, rows.rw[rows.rownum - 1].size);
|
rowAddLast(rows.rw[rows.rownum - 1].chars, rows.rw[rows.rownum - 1].size);
|
||||||
|
|
||||||
for (int last = rows.rownum - 1; last > pos; last--) {
|
/* copy all other lines until the specified position to the next one */
|
||||||
|
for (int last = rows.rownum - 1; last > pos; last--)
|
||||||
rowCpy(&rows.rw[last], &rows.rw[last - 1]);
|
rowCpy(&rows.rw[last], &rows.rw[last - 1]);
|
||||||
}
|
|
||||||
|
|
||||||
//copy previous row
|
/* SPLIT THE ROW AT POS AND STORE IT */
|
||||||
int l = rows.rw[pos].size - t.cur.x;
|
/* Get the row length at position after the cursor */
|
||||||
s = malloc(l + 1);
|
int len = rows.rw[pos].size - t.cur.x;
|
||||||
|
/* create a dummy row as the new row souce */
|
||||||
|
row nex = EROW;
|
||||||
|
/* allocate a buffer */
|
||||||
|
char *s = malloc(len + 1);
|
||||||
if (s == NULL) termDie("malloc in rowAddRow s");
|
if (s == NULL) termDie("malloc in rowAddRow s");
|
||||||
memcpy(s, &rows.rw[pos].chars[t.cur.x], l);
|
/* copy the contents of the pos row after the cursor into the buffer */
|
||||||
s[l] = '\0';
|
memcpy(s, &rows.rw[pos].chars[t.cur.x], len);
|
||||||
// Delete prev row until cursor
|
s[len] = '\0';
|
||||||
char *p = malloc(t.cur.x + 1);
|
/* update the dummy row */
|
||||||
if (p == NULL) termDie("malloc in rowAddRow p");
|
nex.chars = s;
|
||||||
memcpy(p, rows.rw[pos].chars, t.cur.x);
|
nex.size = strlen(s);
|
||||||
p[t.cur.x] = '\0';
|
|
||||||
rowFree(&rows.rw[pos]);
|
/* MAKE THE SPLIT INTO TWO LINES */
|
||||||
rows.rw[pos].chars = malloc(t.cur.x + 1);
|
/* shrink the line at pos */
|
||||||
if (rows.rw[pos].chars == NULL) termDie("malloc in rowAddRow chars until cursor");
|
char *p = realloc(rows.rw[pos].chars, t.cur.x + 1);
|
||||||
memcpy(rows.rw[pos].chars, p, t.cur.x + 1);
|
if (p == NULL) termDie("realloc in rowAddRow");
|
||||||
free(p);
|
rows.rw[pos].chars = p;
|
||||||
|
/* and terminate it with null like a good boi */
|
||||||
|
rows.rw[pos].chars[t.cur.x] = '\0';
|
||||||
|
/* update info and render */
|
||||||
rows.rw[pos].size = t.cur.x;
|
rows.rw[pos].size = t.cur.x;
|
||||||
updateRender(&rows.rw[pos]);
|
updateRender(&rows.rw[pos]);
|
||||||
|
|
||||||
if (pos != rows.rownum - 1) {
|
/* copy the dummy to the new line and free */
|
||||||
rowFree(&rows.rw[pos + 1]);
|
rowCpy(&rows.rw[pos + 1], &nex);
|
||||||
rows.rw[pos + 1].chars = malloc(strlen(s) + 1);
|
rowFree(&nex);
|
||||||
if (rows.rw[pos + 1].chars == NULL) termDie("malloc in rowAddRow chars next row");
|
|
||||||
memcpy(rows.rw[pos + 1].chars, s, strlen(s) + 1);
|
|
||||||
rows.rw[pos + 1].size = strlen(s);
|
|
||||||
updateRender(&rows.rw[pos + 1]);
|
|
||||||
} else rowAddLast(s, l);
|
|
||||||
|
|
||||||
free(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rowFree (row *rw) // WIP
|
void rowFree (row *rw) // WIP
|
||||||
{
|
{
|
||||||
|
/* Free both render and memory strings */
|
||||||
free(rw->render);
|
free(rw->render);
|
||||||
free(rw->chars);
|
free(rw->chars);
|
||||||
|
/* clear sizes */
|
||||||
rw->size = 0;
|
rw->size = 0;
|
||||||
rw->r_size = 0;
|
rw->r_size = 0;
|
||||||
|
rw->utf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rowCpy (row *to, row *from) // WIP
|
void rowCpy (row *to, row *from) // WIP
|
||||||
{
|
{
|
||||||
|
/* Free the destination row (without destroying it) */
|
||||||
rowFree(to);
|
rowFree(to);
|
||||||
|
/* Allocate space for the new string */
|
||||||
to->chars = (char*) malloc(strlen(from->chars) + 1);
|
to->chars = (char*) malloc(strlen(from->chars) + 1);
|
||||||
if (to->chars == NULL) termDie("malloc in rowCpy");
|
if (to->chars == NULL) termDie("malloc in rowCpy");
|
||||||
|
/* And update the size */
|
||||||
to->size = from->size;
|
to->size = from->size;
|
||||||
|
/* Then copy the chars from the source row to the destination row */
|
||||||
memcpy(to->chars, from->chars, to->size);
|
memcpy(to->chars, from->chars, to->size);
|
||||||
to->chars[to->size] = '\0';
|
to->chars[to->size] = '\0';
|
||||||
|
/* Then update the render */
|
||||||
updateRender(to);
|
updateRender(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,20 +649,20 @@ void curUpdateRender ()
|
|||||||
if (isCont(c)) continue;
|
if (isCont(c)) continue;
|
||||||
else if (isStart(c)) t.cur.r_x++;
|
else if (isStart(c)) t.cur.r_x++;
|
||||||
|
|
||||||
if (c == '\t') t.cur.r_x += (TABSIZE - 1) - (t.cur.r_x % TABSIZE);
|
if (c == '\t') t.cur.r_x += (TABSIZE - 1);
|
||||||
|
|
||||||
t.cur.r_x++;
|
t.cur.r_x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.cur.r_x >= t.cur.off_x && t.cur.r_x < t.dim.x) {
|
if (t.cur.r_x >= t.cur.off_x && t.cur.r_x < t.cur.off_x + t.dim.x) {
|
||||||
//ok
|
t.cur.r_x -= t.cur.off_x;
|
||||||
|
|
||||||
} else if (t.cur.r_x < t.cur.off_x) {
|
} else if (t.cur.r_x < t.cur.off_x) {
|
||||||
t.cur.off_x -= t.cur.off_x - t.cur.r_x;
|
t.cur.off_x -= t.cur.off_x - t.cur.r_x;
|
||||||
t.cur.r_x = 0;
|
t.cur.r_x = 0;
|
||||||
|
|
||||||
} else if (t.cur.r_x > t.cur.off_x + t.dim.x) {
|
} else if (t.cur.r_x >= t.cur.off_x + t.dim.x) {
|
||||||
if (t.cur.r_x == t.cur.off_x + t.dim.x) t.cur.off_x++;
|
t.cur.off_x += t.cur.r_x - t.cur.off_x - t.dim.x;
|
||||||
else t.cur.off_x += t.cur.r_x - t.cur.off_x - t.dim.x;
|
|
||||||
t.cur.r_x = t.dim.x;
|
t.cur.r_x = t.dim.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user