|
|
|
@ -22,7 +22,7 @@ struct term { |
|
|
|
|
unsigned int off_x; |
|
|
|
|
unsigned int off_y; |
|
|
|
|
int r_x; |
|
|
|
|
int r_y; |
|
|
|
|
int d_y; |
|
|
|
|
int xx; |
|
|
|
|
int yy; |
|
|
|
|
} cur; |
|
|
|
@ -89,7 +89,7 @@ void fileSave (char *filename); |
|
|
|
|
static void rowAddLast (char *s, int len); |
|
|
|
|
|
|
|
|
|
/* garbage */ |
|
|
|
|
static inline void handleBackspace (void); |
|
|
|
|
static void handleDel (int select); |
|
|
|
|
/* testing */ |
|
|
|
|
static void updateInfo (void); |
|
|
|
|
static int whatsThat (void); |
|
|
|
@ -111,7 +111,6 @@ int main (int argc, char *argv[]) |
|
|
|
|
termInit(); |
|
|
|
|
|
|
|
|
|
/* Set the statusbar left (static) message */ |
|
|
|
|
//caused 74e185d
|
|
|
|
|
snprintf(t.statusbar, STAT_SIZE, "%s %d lines %dx%d", argv[1], rows.rownum, t.dim.y, t.dim.x); |
|
|
|
|
|
|
|
|
|
/* remember the initial row number */ |
|
|
|
@ -135,11 +134,10 @@ int main (int argc, char *argv[]) |
|
|
|
|
cursorMove(c); |
|
|
|
|
break; |
|
|
|
|
case (KEY_BACKSPACE): |
|
|
|
|
handleBackspace(); |
|
|
|
|
break; |
|
|
|
|
handleDel(0); |
|
|
|
|
break; |
|
|
|
|
case (KEY_DC): |
|
|
|
|
rowDeleteChar(&rows.rw[t.cur.yy], 1, t.cur.xx); |
|
|
|
|
handleDel(1); |
|
|
|
|
break; |
|
|
|
|
case (KEY_ENTER): |
|
|
|
|
case (10): |
|
|
|
@ -314,6 +312,37 @@ int curRealToRender (row *rw, int c_x) |
|
|
|
|
return r_x; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void updateRender (row *rw) |
|
|
|
|
{ |
|
|
|
|
/* count the special characters (only tabs for now) */ |
|
|
|
|
static int tabs = 0, i, off; |
|
|
|
|
for (i = 0, tabs = 0; i < rw->size; i++) { |
|
|
|
|
if (rw->chars[i] == '\t') tabs++; |
|
|
|
|
} |
|
|
|
|
rw->render = NULL; |
|
|
|
|
free(rw->render); |
|
|
|
|
|
|
|
|
|
/* Render is long as size with the added tab spaces - 1
|
|
|
|
|
* (we already count for the \t as a char) */ |
|
|
|
|
rw->render = malloc(rw->size + tabs * (TABSIZE - 1) + 1); |
|
|
|
|
if (rw->render == NULL) termDie ("malloc in updateRender"); |
|
|
|
|
|
|
|
|
|
/* put all the characters (substituing all special chars)
|
|
|
|
|
* into the render buffer */ |
|
|
|
|
for (i = 0, off = 0; i < rw->size; i++) { |
|
|
|
|
if (rw->chars[i] == '\t') { |
|
|
|
|
for (int j = 0; j < TABSIZE; j++){ |
|
|
|
|
if (!j) rw->render[off++] = '|';
|
|
|
|
|
else rw->render[off++] = ' '; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
rw->render[off++] = rw->chars[i]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
rw->render[off] = '\0'; |
|
|
|
|
rw->r_size = off; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* -------------------------------- draw operations -------------------------------- */ |
|
|
|
|
|
|
|
|
|
/* Open a file and put it into a buffer line by line */ |
|
|
|
@ -341,6 +370,8 @@ void fileOpen (char *filename) |
|
|
|
|
fclose(fp); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*------------------------------------- file operations ----------------------------------*/ |
|
|
|
|
|
|
|
|
|
/* Add a row to the file buffer */ |
|
|
|
|
void rowAddLast (char *s, int len) |
|
|
|
|
{ |
|
|
|
@ -360,37 +391,6 @@ void rowAddLast (char *s, int len) |
|
|
|
|
rows.rownum++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void updateRender (row *rw) |
|
|
|
|
{ |
|
|
|
|
/* count the special characters (only tabs for now) */ |
|
|
|
|
static int tabs = 0, i, off; |
|
|
|
|
for (i = 0, tabs = 0; i < rw->size; i++) { |
|
|
|
|
if (rw->chars[i] == '\t') tabs++; |
|
|
|
|
} |
|
|
|
|
rw->render = NULL; |
|
|
|
|
free(rw->render); |
|
|
|
|
|
|
|
|
|
/* Render is long as size with the added tab spaces - 1
|
|
|
|
|
* (we already count for the \t as a char) */ |
|
|
|
|
rw->render = malloc(rw->size + tabs * (TABSIZE - 1) + 1); |
|
|
|
|
if (rw->render == NULL) termDie ("malloc in updateRender"); |
|
|
|
|
|
|
|
|
|
/* put all the characters (substituing all special chars)
|
|
|
|
|
* into the render buffer */ |
|
|
|
|
for (i = 0, off = 0; i < rw->size; i++) { |
|
|
|
|
if (rw->chars[i] == '\t') { |
|
|
|
|
for (int j = 0; j < TABSIZE; j++){ |
|
|
|
|
if (!j) rw->render[off++] = '|';
|
|
|
|
|
else rw->render[off++] = ' '; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
rw->render[off++] = rw->chars[i]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
rw->render[off] = '\0'; |
|
|
|
|
rw->r_size = off; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowInit (void) |
|
|
|
|
{ |
|
|
|
|
rows.rw = NULL; |
|
|
|
@ -465,7 +465,101 @@ void rowDeleteChar (row *rw, int select, int pos) // WIP |
|
|
|
|
updateRender(rw); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ----------------------------- file operations --------------------------- */ |
|
|
|
|
void rowAddRow (int pos) // WIP; TO DOCUMENT |
|
|
|
|
{ |
|
|
|
|
char *s = NULL; |
|
|
|
|
// Move away other lines
|
|
|
|
|
//copy old last line to new space
|
|
|
|
|
rowAddLast(rows.rw[rows.rownum - 1].chars, rows.rw[rows.rownum - 1].size); |
|
|
|
|
|
|
|
|
|
for (int last = rows.rownum - 1; last > pos; last--) { |
|
|
|
|
rowCpy(&rows.rw[last], &rows.rw[last - 1]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//copy previous row
|
|
|
|
|
int l = rows.rw[pos].size - t.cur.xx; |
|
|
|
|
s = malloc(l + 1); |
|
|
|
|
if (s == NULL) termDie("malloc in rowAddRow s"); |
|
|
|
|
memcpy(s, &rows.rw[pos].chars[t.cur.xx], l); |
|
|
|
|
s[l] = '\0'; |
|
|
|
|
// Delete prev row until cursor
|
|
|
|
|
char *p = malloc(t.cur.xx + 1); |
|
|
|
|
if (p == NULL) termDie("malloc in rowAddRow p"); |
|
|
|
|
memcpy(p, rows.rw[pos].chars, t.cur.xx); |
|
|
|
|
p[t.cur.xx] = '\0'; |
|
|
|
|
rowFree(&rows.rw[pos]); |
|
|
|
|
rows.rw[pos].chars = malloc(t.cur.xx + 1); |
|
|
|
|
if (rows.rw[pos].chars == NULL) termDie("malloc in rowAddRow chars until cursor"); |
|
|
|
|
memcpy(rows.rw[pos].chars, p, t.cur.xx + 1); |
|
|
|
|
free(p); |
|
|
|
|
rows.rw[pos].size = t.cur.xx; |
|
|
|
|
updateRender(&rows.rw[pos]); |
|
|
|
|
|
|
|
|
|
if (pos != rows.rownum - 1) { |
|
|
|
|
rowFree(&rows.rw[pos + 1]); |
|
|
|
|
rows.rw[pos + 1].chars = malloc(strlen(s) + 1); |
|
|
|
|
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); |
|
|
|
|
t.cur.y++; |
|
|
|
|
t.cur.x = 0; |
|
|
|
|
t.cur.off_x = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowFree (row *rw) // WIP
|
|
|
|
|
{ |
|
|
|
|
free(rw->render); |
|
|
|
|
free(rw->chars); |
|
|
|
|
rw->size = 0; |
|
|
|
|
rw->r_size = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowCpy (row *to, row *from) // WIP
|
|
|
|
|
{
|
|
|
|
|
rowFree(to); |
|
|
|
|
to->chars = (char*) malloc(strlen(from->chars) + 1); |
|
|
|
|
if (to->chars == NULL) termDie("malloc in rowCpy"); |
|
|
|
|
to->size = from->size; |
|
|
|
|
memcpy(to->chars, from->chars, to->size); |
|
|
|
|
to->chars[to->size] = '\0'; |
|
|
|
|
updateRender(to); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowAddString (row *rw, char *s, int len, int pos) |
|
|
|
|
{ |
|
|
|
|
char *temp = realloc(rw->chars, rw->size + len + 1); |
|
|
|
|
if (temp == NULL) termDie("realloc in rowAddString"); |
|
|
|
|
rw->chars = temp; |
|
|
|
|
if (pos == -1 || pos == rw->size) { |
|
|
|
|
memcpy(&rw->chars[rw->size], s, len); |
|
|
|
|
rw->size += len; |
|
|
|
|
rw->chars[rw->size] = '\0'; |
|
|
|
|
} else { |
|
|
|
|
memcpy(&rw->chars[rw->size], &rw->chars[rw->size - len], len); |
|
|
|
|
memcpy(&rw->chars[rw->size - len], s, len); |
|
|
|
|
rw->size += len; |
|
|
|
|
rw->chars[rw->size] = '\0'; |
|
|
|
|
} |
|
|
|
|
updateRender(rw); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowDeleteRow (int pos) |
|
|
|
|
{ |
|
|
|
|
for (; pos < rows.rownum - 1; pos++) { |
|
|
|
|
rowCpy(&rows.rw[pos], &rows.rw[pos + 1]); // rowcpy already frees the row
|
|
|
|
|
} |
|
|
|
|
rows.rownum--; |
|
|
|
|
rowFree(&rows.rw[rows.rownum]); |
|
|
|
|
row *temp = realloc(rows.rw, sizeof(row) * rows.rownum); |
|
|
|
|
if (temp == NULL) termDie("malloc in rowDeleteRow"); |
|
|
|
|
rows.rw = temp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ----------------------------- row operations --------------------------- */ |
|
|
|
|
|
|
|
|
|
/* take care of the cursor movement */ |
|
|
|
|
void cursorMove (int a) |
|
|
|
@ -548,6 +642,7 @@ void updateScroll (void) |
|
|
|
|
t.cur.yy = t.cur.y + t.cur.off_y; |
|
|
|
|
t.cur.xx = t.cur.x + t.cur.off_x; |
|
|
|
|
t.cur.r_x = curRealToRender(&rows.rw[t.cur.yy], t.cur.x); |
|
|
|
|
t.cur.d_x = t.cur.r_x - t.cur.x; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*---------------------------------- scroll ------------------------------------*/ |
|
|
|
@ -572,110 +667,26 @@ int whatsThat (void) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowAddRow (int pos) // WIP; TO DOCUMENT |
|
|
|
|
{ |
|
|
|
|
char *s = NULL; |
|
|
|
|
// Move away other lines
|
|
|
|
|
//copy old last line to new space
|
|
|
|
|
rowAddLast(rows.rw[rows.rownum - 1].chars, rows.rw[rows.rownum - 1].size); |
|
|
|
|
|
|
|
|
|
for (int last = rows.rownum - 1; last > pos; last--) { |
|
|
|
|
rowCpy(&rows.rw[last], &rows.rw[last - 1]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//copy previous row
|
|
|
|
|
int l = rows.rw[pos].size - t.cur.xx; |
|
|
|
|
s = malloc(l + 1); |
|
|
|
|
if (s == NULL) termDie("malloc in rowAddRow s"); |
|
|
|
|
memcpy(s, &rows.rw[pos].chars[t.cur.xx], l); |
|
|
|
|
s[l] = '\0'; |
|
|
|
|
// Delete prev row until cursor
|
|
|
|
|
char *p = malloc(t.cur.xx + 1); |
|
|
|
|
if (p == NULL) termDie("malloc in rowAddRow p"); |
|
|
|
|
memcpy(p, rows.rw[pos].chars, t.cur.xx); |
|
|
|
|
p[t.cur.xx] = '\0'; |
|
|
|
|
rowFree(&rows.rw[pos]); |
|
|
|
|
rows.rw[pos].chars = malloc(t.cur.xx + 1); |
|
|
|
|
if (rows.rw[pos].chars == NULL) termDie("malloc in rowAddRow chars until cursor"); |
|
|
|
|
memcpy(rows.rw[pos].chars, p, t.cur.xx + 1); |
|
|
|
|
free(p); |
|
|
|
|
rows.rw[pos].size = t.cur.xx; |
|
|
|
|
updateRender(&rows.rw[pos]); |
|
|
|
|
|
|
|
|
|
if (pos != rows.rownum - 1) { |
|
|
|
|
rowFree(&rows.rw[pos + 1]); |
|
|
|
|
rows.rw[pos + 1].chars = malloc(strlen(s) + 1); |
|
|
|
|
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); |
|
|
|
|
t.cur.y++; |
|
|
|
|
t.cur.x = 0; |
|
|
|
|
t.cur.off_x = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowFree (row *rw) // WIP
|
|
|
|
|
{ |
|
|
|
|
free(rw->render); |
|
|
|
|
free(rw->chars); |
|
|
|
|
rw->size = 0; |
|
|
|
|
rw->r_size = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowCpy (row *to, row *from) // WIP
|
|
|
|
|
{
|
|
|
|
|
rowFree(to); |
|
|
|
|
to->chars = (char*) malloc(strlen(from->chars) + 1); |
|
|
|
|
if (to->chars == NULL) termDie("malloc in rowCpy"); |
|
|
|
|
to->size = from->size; |
|
|
|
|
memcpy(to->chars, from->chars, to->size); |
|
|
|
|
to->chars[to->size] = '\0'; |
|
|
|
|
updateRender(to); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowAddString (row *rw, char *s, int len, int pos) |
|
|
|
|
{ |
|
|
|
|
char *temp = realloc(rw->chars, rw->size + len + 1); |
|
|
|
|
if (temp == NULL) termDie("realloc in rowAddString"); |
|
|
|
|
rw->chars = temp; |
|
|
|
|
if (pos == -1 || pos == rw->size) { |
|
|
|
|
memcpy(&rw->chars[rw->size], s, len); |
|
|
|
|
rw->size += len; |
|
|
|
|
rw->chars[rw->size] = '\0'; |
|
|
|
|
} else { |
|
|
|
|
memcpy(&rw->chars[rw->size], &rw->chars[rw->size - len], len); |
|
|
|
|
memcpy(&rw->chars[rw->size - len], s, len); |
|
|
|
|
rw->size += len; |
|
|
|
|
rw->chars[rw->size] = '\0'; |
|
|
|
|
} |
|
|
|
|
updateRender(rw); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handleBackspace (void) |
|
|
|
|
{ |
|
|
|
|
if (t.cur.x <= 0 && t.cur.yy > 0) { |
|
|
|
|
t.cur.x = rows.rw[t.cur.yy - 1].size; |
|
|
|
|
rowAddString(&rows.rw[t.cur.yy - 1], rows.rw[t.cur.yy].chars, rows.rw[t.cur.yy].size, -1); |
|
|
|
|
rowDeleteRow(t.cur.yy); |
|
|
|
|
t.cur.y--; |
|
|
|
|
void handleDel (int select) |
|
|
|
|
{
|
|
|
|
|
if (!select) { |
|
|
|
|
if (t.cur.xx <= 0 && t.cur.yy > 0) { |
|
|
|
|
t.cur.x = rows.rw[t.cur.yy - 1].size; |
|
|
|
|
rowAddString(&rows.rw[t.cur.yy - 1], rows.rw[t.cur.yy].chars, rows.rw[t.cur.yy].size, -1); |
|
|
|
|
rowDeleteRow(t.cur.yy); |
|
|
|
|
t.cur.y--; |
|
|
|
|
} else { |
|
|
|
|
rowDeleteChar(&rows.rw[t.cur.yy], 0, t.cur.xx); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
rowDeleteChar(&rows.rw[t.cur.yy], 0, t.cur.xx); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rowDeleteRow (int pos) |
|
|
|
|
{ |
|
|
|
|
for (; pos < rows.rownum - 1; pos++) { |
|
|
|
|
rowCpy(&rows.rw[pos], &rows.rw[pos + 1]); // rowcpy already frees the row
|
|
|
|
|
if (t.cur.xx >= rows.rw[t.cur.yy].size) { |
|
|
|
|
rowAddString(&rows.rw[t.cur.yy], rows.rw[t.cur.yy + 1].chars, rows.rw[t.cur.yy + 1].size, -1); |
|
|
|
|
rowDeleteRow(t.cur.yy + 1); |
|
|
|
|
} else { |
|
|
|
|
rowDeleteChar(&rows.rw[t.cur.yy], 1, t.cur.xx); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
rows.rownum--; |
|
|
|
|
rowFree(&rows.rw[rows.rownum]); |
|
|
|
|
row *temp = realloc(rows.rw, sizeof(row) * rows.rownum); |
|
|
|
|
if (temp == NULL) termDie("malloc in rowDeleteRow"); |
|
|
|
|
rows.rw = temp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*--------------------------------- garbage ------------------------------------*/ |
|
|
|
|