parent
a2bfacedba
commit
51fe76b5e8
@ -1,7 +1,7 @@ |
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-Wall -Wextra -pedantic -Werror
|
CFLAGS=-Wall -Wextra -pedantic -Werror
|
||||||
OFLAGS=-O3
|
OFLAGS=-O3
|
||||||
LFLAGS=-lncurses
|
LFLAGS=-lncurses
|
||||||
|
|
||||||
ste: ste.c |
ste: ste.c |
||||||
$(CC) $(CFLAGS) $(OFLAGS) $(LFLAGS) -o ste $^
|
$(CC) $(CFLAGS) $(OFLAGS) $(LFLAGS) -o ste $^
|
@ -1,464 +1,476 @@ |
|||||||
#include <ncurses.h> |
#include <ncurses.h> |
||||||
#include <stdlib.h> |
#include <stdlib.h> |
||||||
#include <string.h> |
#include <string.h> |
||||||
|
|
||||||
/* defines */ |
/* defines */ |
||||||
#define CTRL(k) ((k) & 0x1f) // Control mask modifier
|
#define CTRL(k) ((k) & 0x1f) // Control mask modifier
|
||||||
#define TABSIZE 4 // Tab size as used in render
|
#define TABSIZE 4 // Tab size as used in render
|
||||||
|
|
||||||
/* main data structure containing:
|
/* main data structure containing:
|
||||||
* -cursor position |
* -cursor position |
||||||
* -real (matching memory) |
* -real (matching memory) |
||||||
* -offset (memory and screen offset) |
* -offset (memory and screen offset) |
||||||
* -render (drawn on the screen) |
* -render (drawn on the screen) |
||||||
* -window size |
* -window size |
||||||
* -statusbar message */ |
* -statusbar message */ |
||||||
struct term { |
struct term { |
||||||
struct { |
struct { |
||||||
int x; |
int x; |
||||||
int y; |
int y; |
||||||
int off_x; |
int off_x; |
||||||
int off_y; |
int off_y; |
||||||
int r_x; |
int r_x; |
||||||
int r_y; |
int r_y; |
||||||
} cur; |
} cur; |
||||||
|
|
||||||
struct { |
struct { |
||||||
int x; |
int x; |
||||||
int y; |
int y; |
||||||
} dim; |
} dim; |
||||||
|
|
||||||
char statusbar[30]; |
char statusbar[30]; |
||||||
int pad; |
int pad; |
||||||
} t; |
} t; |
||||||
|
|
||||||
/* 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 */ |
||||||
typedef struct row { |
typedef struct row { |
||||||
int size; |
int size; |
||||||
char *chars; |
char *chars; |
||||||
int r_size; |
int r_size; |
||||||
char *render; |
char *render; |
||||||
int delta; |
int delta; |
||||||
} row; |
} row; |
||||||
|
|
||||||
/* Rows structure (or file buffer)
|
/* Rows structure (or file buffer)
|
||||||
* defines rows and teh number of rows */ |
* defines rows and teh number of rows */ |
||||||
struct { |
struct { |
||||||
row *rw; |
row *rw; |
||||||
int rownum; |
int rownum; |
||||||
} rows; |
} rows; |
||||||
|
|
||||||
/* Prototypes */ |
/* Prototypes */ |
||||||
/* draw operations */ |
/* draw operations */ |
||||||
static void drawBar (char *s); |
static void drawBar (char *s); |
||||||
static void drawScreen (); |
static void drawScreen (); |
||||||
static void drawLines (void); |
static void drawLines (void); |
||||||
static void updateRender (row *rw); |
static void updateRender (row *rw); |
||||||
static void updateScroll (void); |
static void updateScroll (void); |
||||||
static void cursorMove(int a); |
static void cursorMove(int a); |
||||||
static int getLineNumberSize (void); |
static int getLineNumberSize (void); |
||||||
static void lnMove (int y, int x); |
static void lnMove (int y, int x); |
||||||
static int curRealToRender (row *rw, int c_x); |
static int curRealToRender (row *rw, int c_x); |
||||||
|
|
||||||
/* Row operations */ |
/* Row operations */ |
||||||
static inline void rowInit (void); |
static inline void rowInit (void); |
||||||
|
|
||||||
/* Terminal operations */ |
/* Terminal operations */ |
||||||
static void termInit (void); |
static void termInit (void); |
||||||
static void termExit (void); |
static void termExit (void); |
||||||
static void termDie (char *s); |
static void termDie (char *s); |
||||||
|
|
||||||
/* file operations */ |
/* file operations */ |
||||||
static void fileOpen (char *filename); |
static void fileOpen (char *filename); |
||||||
void fileSave (char *filename); |
void fileSave (char *filename); |
||||||
|
|
||||||
/* buffer operations */ |
/* buffer operations */ |
||||||
static void rowAdd (char *s, int len); |
static void rowAdd (char *s, int len); |
||||||
|
|
||||||
/* garbage */ |
/* garbage */ |
||||||
//inline void bufferFree (void);
|
//inline void bufferFree (void);
|
||||||
static int whatsThat (void); |
static int whatsThat (void); |
||||||
|
|
||||||
/* --------------------------------- main ------------------------------------ */ |
/* testing */ |
||||||
int main (int argc, char *argv[]) |
void updateInfo (void); |
||||||
{ |
|
||||||
/* Initialize the first row */ |
/* --------------------------------- main ------------------------------------ */ |
||||||
rowInit(); |
int main (int argc, char *argv[]) |
||||||
|
{ |
||||||
/* Try to open the file */ |
/* Initialize the first row */ |
||||||
if (argc != 2) { |
rowInit(); |
||||||
perror("File not found"); |
|
||||||
exit(1); |
/* Try to open the file */ |
||||||
} else fileOpen(argv[1]); |
if (argc != 2) { |
||||||
|
perror("File not found"); |
||||||
/* Initialize the terminal in raw mode,
|
exit(1); |
||||||
* start curses and initialize the term struct */ |
} else fileOpen(argv[1]); |
||||||
termInit(); |
|
||||||
|
/* Initialize the terminal in raw mode,
|
||||||
/* Set the statusbar left (static) message */ |
* start curses and initialize the term struct */ |
||||||
sprintf(t.statusbar, "%s : %s %d lines %dx%d", argv[0], argv[1], rows.rownum, t.dim.y, t.dim.y); |
termInit(); |
||||||
|
|
||||||
/* Main event loop */ |
/* Set the statusbar left (static) message */ |
||||||
int c; |
sprintf(t.statusbar, "%s : %s %d lines %dx%d", argv[0], argv[1], rows.rownum, t.dim.y, t.dim.y); |
||||||
while (1) { |
|
||||||
/* Redraw the screen */ |
/* Main event loop */ |
||||||
drawScreen(); |
int c; |
||||||
|
while (1) { |
||||||
/* Wait for an event (keypress) */ |
/* Redraw the screen */ |
||||||
switch (c = getch()) { |
drawScreen(); |
||||||
case (CTRL('q')): |
|
||||||
termExit(); |
/* Wait for an event (keypress) */ |
||||||
break; |
switch (c = getch()) { |
||||||
case (KEY_LEFT): |
case (CTRL('q')): |
||||||
case (KEY_RIGHT): |
termExit(); |
||||||
case (KEY_UP): |
break; |
||||||
case (KEY_DOWN): |
case (KEY_LEFT): |
||||||
cursorMove(c); |
case (KEY_RIGHT): |
||||||
break; |
case (KEY_UP): |
||||||
} |
case (KEY_DOWN): |
||||||
} |
cursorMove(c); |
||||||
|
break; |
||||||
/* If by chance i find myself here be sure
|
} |
||||||
* end curses mode and clenaup */ |
} |
||||||
termExit(); |
|
||||||
return 0; |
/* If by chance i find myself here be sure
|
||||||
} |
* end curses mode and clenaup */ |
||||||
|
termExit(); |
||||||
/* ----------------------------- end of main ---------------------------------- */ |
return 0; |
||||||
|
} |
||||||
void termInit (void) |
|
||||||
{ |
/* ----------------------------- end of main ---------------------------------- */ |
||||||
/* Init the screen and refresh */ |
|
||||||
initscr(); |
void termInit (void) |
||||||
refresh(); |
{ |
||||||
|
/* Init the screen and refresh */ |
||||||
/* Enable raw mode, this makes the termianl ignore
|
initscr(); |
||||||
* interrupt signals like CTRL+C and CTRL+Z |
refresh(); |
||||||
* allowing us to make our own bindings */ |
|
||||||
raw(); |
/* Enable raw mode, this makes the termianl ignore
|
||||||
|
* interrupt signals like CTRL+C and CTRL+Z |
||||||
/* Allow use of function keys */ |
* allowing us to make our own bindings */ |
||||||
keypad(stdscr, TRUE); |
raw(); |
||||||
|
|
||||||
/* Turn off echoing */ |
/* Allow use of function keys */ |
||||||
noecho(); |
keypad(stdscr, TRUE); |
||||||
|
|
||||||
/* Set the tab size */ |
/* Turn off echoing */ |
||||||
set_tabsize(TABSIZE); |
noecho(); |
||||||
|
|
||||||
/* Start color mode */ |
/* Set the tab size */ |
||||||
start_color(); |
set_tabsize(TABSIZE); |
||||||
init_pair(1, COLOR_BLUE, COLOR_BLACK); |
|
||||||
|
/* Start color mode */ |
||||||
/* Populate the main data structure */ |
start_color(); |
||||||
getmaxyx(stdscr, t.dim.y, t.dim.x); |
init_pair(1, COLOR_BLUE, COLOR_BLACK); |
||||||
t.dim.y -= 1; |
|
||||||
t.pad = getLineNumberSize(); |
/* Populate the main data structure */ |
||||||
t.dim.x -= t.pad + 1; |
getmaxyx(stdscr, t.dim.y, t.dim.x); |
||||||
|
t.dim.y -= 1; |
||||||
/* Initialize the data staructure */ |
t.pad = getLineNumberSize(); |
||||||
t.cur.x = t.cur.off_x = 0; |
t.dim.x -= t.pad + 1; |
||||||
t.cur.y = t.cur.off_y = 0; |
|
||||||
} |
/* Initialize the data staructure */ |
||||||
|
t.cur.x = t.cur.off_x = 0; |
||||||
/* Calculate the correct spacing for the line numbers
|
t.cur.y = t.cur.off_y = 0; |
||||||
* based on the size of the file */ |
} |
||||||
int getLineNumberSize (void) |
|
||||||
{ |
/* Calculate the correct spacing for the line numbers
|
||||||
int n = rows.rownum, l = 0; |
* based on the size of the file */ |
||||||
for (l = 0; n > 0; l++) n /= 10; |
int getLineNumberSize (void) |
||||||
return l + 1; |
{ |
||||||
} |
int n = rows.rownum, l = 0; |
||||||
|
for (l = 0; n > 0; l++) n /= 10; |
||||||
void termExit (void) |
return l + 1; |
||||||
{ |
} |
||||||
// bufferFree();
|
|
||||||
erase(); |
void termExit (void) |
||||||
refresh(); |
{ |
||||||
endwin(); |
// bufferFree();
|
||||||
exit(0); |
erase(); |
||||||
} |
refresh(); |
||||||
|
endwin(); |
||||||
void termDie (char *s) |
exit(0); |
||||||
{ |
} |
||||||
refresh(); |
|
||||||
endwin(); |
void termDie (char *s) |
||||||
perror(s); |
{ |
||||||
exit(1); |
refresh(); |
||||||
} |
endwin(); |
||||||
|
perror(s); |
||||||
/* ----------------------------- term operations -------------------------------- */ |
exit(1); |
||||||
|
} |
||||||
void drawScreen () |
|
||||||
{ |
/* ----------------------------- term operations -------------------------------- */ |
||||||
/* Clear the screen */ |
|
||||||
erase(); |
void drawScreen () |
||||||
/* Update Scroll */ |
{ |
||||||
updateScroll(); |
/* Clear the screen */ |
||||||
/* draw the lines */ |
erase(); |
||||||
drawLines(); |
/* Update Scroll */ |
||||||
/* draw the bar */ |
updateScroll(); |
||||||
drawBar(t.statusbar); |
/* draw the lines */ |
||||||
/* move back to the cursor position */ |
drawLines(); |
||||||
lnMove(t.cur.y, t.cur.r_x); |
/* draw the bar */ |
||||||
/* refresh the screen */ |
drawBar(t.statusbar); |
||||||
refresh(); |
/* move back to the cursor position */ |
||||||
} |
lnMove(t.cur.y, t.cur.r_x); |
||||||
|
/* refresh the screen */ |
||||||
/* Draw all the appropriate lines (following cursor) to the screen */ |
refresh(); |
||||||
void drawLines (void) |
} |
||||||
{ |
|
||||||
int line = 0, ln; |
/* Draw all the appropriate lines (following cursor) to the screen */ |
||||||
/* move to the beginning of the screen */ |
void drawLines (void) |
||||||
lnMove(0, 0); |
{ |
||||||
|
int line = 0, ln; |
||||||
for (int i = 0; i < t.dim.y; i++) { |
/* move to the beginning of the screen */ |
||||||
if (i >= rows.rownum) break; |
lnMove(0, 0); |
||||||
ln = i + t.cur.off_y; |
|
||||||
|
for (int i = 0; i < t.dim.y; i++) { |
||||||
/* Draw the line number */ |
if (i >= rows.rownum) break; |
||||||
attron(COLOR_PAIR(1)); |
ln = i + t.cur.off_y; |
||||||
mvprintw(i, 0, "%d", ln + 1); |
|
||||||
attroff(COLOR_PAIR(1)); |
/* Draw the line number */ |
||||||
lnMove(i, 0); |
attron(COLOR_PAIR(1)); |
||||||
|
mvprintw(i, 0, "%d", ln + 1); |
||||||
/* Draw the line matcing render memory */ |
attroff(COLOR_PAIR(1)); |
||||||
if (rows.rw[ln].r_size >= t.cur.off_x) { |
lnMove(i, 0); |
||||||
addnstr(&rows.rw[ln].render[t.cur.off_x], t.dim.x + 1 - rows.rw[ln].delta); |
|
||||||
} |
/* Draw the line matcing render memory */ |
||||||
lnMove(++line, 0); |
if (rows.rw[ln].r_size >= t.cur.off_x) { |
||||||
} |
addnstr(&rows.rw[ln].render[t.cur.off_x], t.dim.x + 1 - rows.rw[ln].delta); |
||||||
lnMove(t.cur.y, t.cur.x); |
} |
||||||
} |
lnMove(++line, 0); |
||||||
|
} |
||||||
/* Move avoiding the space allocated for line numbers */ |
lnMove(t.cur.y, t.cur.x); |
||||||
void lnMove (int y, int x) |
} |
||||||
{ |
|
||||||
x += t.pad; |
/* Move avoiding the space allocated for line numbers */ |
||||||
move(y, x); |
void lnMove (int y, int x) |
||||||
} |
{ |
||||||
|
x += t.pad; |
||||||
/* Draw the status bar at the bottom of the screen */ |
move(y, x); |
||||||
void drawBar (char *s) |
} |
||||||
{ |
|
||||||
/* Set maximum contrast for bar */ |
/* Draw the status bar at the bottom of the screen */ |
||||||
attron(A_STANDOUT); |
void drawBar (char *s) |
||||||
/* get the length of the statusbar text */ |
{ |
||||||
int len = strlen(s); |
/* Set maximum contrast for bar */ |
||||||
/* Print the message */ |
attron(A_STANDOUT); |
||||||
mvprintw(t.dim.y, 0, s); |
/* get the length of the statusbar text */ |
||||||
/* Fill everything else with spaces */ |
int len = strlen(s); |
||||||
for (int i = len; i <= t.dim.x + t.pad; i++) |
/* Print the message */ |
||||||
mvaddch(t.dim.y, i, ' '); |
mvprintw(t.dim.y, 0, s); |
||||||
|
/* Fill everything else with spaces */ |
||||||
char m[10]; |
for (int i = len; i <= t.dim.x + t.pad; i++) |
||||||
sprintf(m, "Zoom:\t%c", whatsThat()); |
mvaddch(t.dim.y, i, ' '); |
||||||
mvaddstr(t.dim.y, t.dim.x + t.pad - strlen(m), m); |
|
||||||
|
char m[10]; |
||||||
/* Return to normal contrast mode */ |
sprintf(m, "Zoom:\t%c", whatsThat()); |
||||||
attroff(A_STANDOUT); |
mvaddstr(t.dim.y, t.dim.x + t.pad - strlen(m), m); |
||||||
} |
|
||||||
|
/* Return to normal contrast mode */ |
||||||
/* convert the cursor matchoing the memory to the drawn one */ |
attroff(A_STANDOUT); |
||||||
int curRealToRender (row *rw, int c_x) |
} |
||||||
{ |
|
||||||
int r_x = 0; |
/* convert the cursor matchoing the memory to the drawn one */ |
||||||
for (int i = 0; i < c_x; i++) { |
int curRealToRender (row *rw, int c_x) |
||||||
if (rw->chars[i] == '\t') r_x += (TABSIZE - 1) - (r_x % TABSIZE); |
{ |
||||||
r_x++; |
int r_x = 0; |
||||||
} |
for (int i = 0; i < c_x; i++) { |
||||||
return r_x; |
if (rw->chars[i] == '\t') r_x += (TABSIZE - 1) - (r_x % TABSIZE); |
||||||
} |
r_x++; |
||||||
|
} |
||||||
/* -------------------------------- draw operations -------------------------------- */ |
return r_x; |
||||||
|
} |
||||||
/* Open a file and put it into a buffer line by line */ |
|
||||||
void fileOpen (char *filename) |
/* -------------------------------- draw operations -------------------------------- */ |
||||||
{ |
|
||||||
FILE *fp = fopen(filename, "r"); |
/* Open a file and put it into a buffer line by line */ |
||||||
if (!fp) termDie("Cannot open file"); |
void fileOpen (char *filename) |
||||||
|
{ |
||||||
/* Init the linebuffer */ |
FILE *fp = fopen(filename, "r"); |
||||||
char *line = NULL; |
if (!fp) termDie("Cannot open file"); |
||||||
/* Set linecap to 0 so getline will atumatically allocate
|
|
||||||
* memory for the line buffer*/ |
/* Init the linebuffer */ |
||||||
size_t linecap = 0; |
char *line = NULL; |
||||||
ssize_t linelen; |
/* Set linecap to 0 so getline will atumatically allocate
|
||||||
|
* memory for the line buffer*/ |
||||||
/* getline returns -1 if no new line is present */ |
size_t linecap = 0; |
||||||
while ((linelen = getline(&line, &linecap, fp)) != -1) { |
ssize_t linelen; |
||||||
while (linelen > 0 && (line[linelen - 1] == '\n' || line[linelen - 1] == '\r')) |
|
||||||
linelen--; |
/* getline returns -1 if no new line is present */ |
||||||
rowAdd(line, linelen); |
while ((linelen = getline(&line, &linecap, fp)) != -1) { |
||||||
} |
while (linelen > 0 && (line[linelen - 1] == '\n' || line[linelen - 1] == '\r')) |
||||||
/* free the line buffer */ |
linelen--; |
||||||
free(line); |
rowAdd(line, linelen); |
||||||
/* close the file */ |
} |
||||||
fclose(fp); |
/* free the line buffer */ |
||||||
} |
free(line); |
||||||
|
/* close the file */ |
||||||
/* Add a row to the file buffer */ |
fclose(fp); |
||||||
void rowAdd (char *s, int len) |
} |
||||||
{ |
|
||||||
/* Extend the block of memory containing the lines */ |
/* Add a row to the file buffer */ |
||||||
rows.rw = realloc(rows.rw, sizeof(row) * (rows.rownum + 1)); |
void rowAdd (char *s, int len) |
||||||
|
{ |
||||||
/* Allocate memory for the line and copy it
|
/* Extend the block of memory containing the lines */ |
||||||
* at the current row number */ |
rows.rw = realloc(rows.rw, sizeof(row) * (rows.rownum + 1)); |
||||||
rows.rw[rows.rownum].chars = malloc(len + 1); |
|
||||||
memcpy(rows.rw[rows.rownum].chars, s, len); |
/* Allocate memory for the line and copy it
|
||||||
rows.rw[rows.rownum].chars[len] = '\0'; |
* at the current row number */ |
||||||
rows.rw[rows.rownum].size = len; |
rows.rw[rows.rownum].chars = malloc(len + 1); |
||||||
updateRender(&rows.rw[rows.rownum]); |
memcpy(rows.rw[rows.rownum].chars, s, len); |
||||||
rows.rownum++; |
rows.rw[rows.rownum].chars[len] = '\0'; |
||||||
} |
rows.rw[rows.rownum].size = len; |
||||||
|
updateRender(&rows.rw[rows.rownum]); |
||||||
void updateRender (row *rw) |
rows.rownum++; |
||||||
{ |
} |
||||||
/* count the special characters (only tabs for now) */ |
|
||||||
int tabs = 0, i; |
void updateRender (row *rw) |
||||||
for (i = 0; i < rw->size; i++) { |
{ |
||||||
if (rw->chars[i] == '\t') tabs++; |
/* count the special characters (only tabs for now) */ |
||||||
} |
int tabs = 0, i; |
||||||
rw->render = NULL; |
for (i = 0; i < rw->size; i++) { |
||||||
free(rw->render); |
if (rw->chars[i] == '\t') tabs++; |
||||||
|
} |
||||||
/* Render is long as size with the added tab spaces - 1
|
rw->render = NULL; |
||||||
* (we already count for the \t as a char) */ |
free(rw->render); |
||||||
rw->render = malloc(rw->size + tabs * (TABSIZE - 1) + 1); |
|
||||||
|
/* Render is long as size with the added tab spaces - 1
|
||||||
if (rw->render == NULL) termDie ("malloc in updateRender"); |
* (we already count for the \t as a char) */ |
||||||
|
rw->render = malloc(rw->size + tabs * (TABSIZE - 1) + 1); |
||||||
/* put all the characters (substituing all special chars)
|
|
||||||
* into the render buffer */ |
if (rw->render == NULL) termDie ("malloc in updateRender"); |
||||||
int off = 0; |
|
||||||
for (i = 0; i < rw->size; i++) { |
/* put all the characters (substituing all special chars)
|
||||||
if (rw->chars[i] == '\t') { |
* into the render buffer */ |
||||||
for (int j = 0; j < TABSIZE; j++) |
int off = 0; |
||||||
rw->render[off++] = ' '; |
for (i = 0; i < rw->size; i++) { |
||||||
} else { |
if (rw->chars[i] == '\t') { |
||||||
rw->render[off++] = rw->chars[i]; |
for (int j = 0; j < TABSIZE; j++) |
||||||
} |
rw->render[off++] = ' '; |
||||||
} |
} else { |
||||||
rw->render[off] = '\0'; |
rw->render[off++] = rw->chars[i]; |
||||||
rw->r_size = off; |
} |
||||||
} |
} |
||||||
|
rw->render[off] = '\0'; |
||||||
void rowInit (void) |
rw->r_size = off; |
||||||
{ |
} |
||||||
rows.rw = NULL; |
|
||||||
rows.rownum = 0; |
void rowInit (void) |
||||||
} |
{ |
||||||
|
rows.rw = NULL; |
||||||
/* ----------------------------- file operations --------------------------- */ |
rows.rownum = 0; |
||||||
|
} |
||||||
/* take care of the cursor movement */ |
|
||||||
void cursorMove (int a) |
/* ----------------------------- file operations --------------------------- */ |
||||||
{ |
|
||||||
switch (a) { |
/* take care of the cursor movement */ |
||||||
case (KEY_LEFT): |
void cursorMove (int a) |
||||||
if (t.cur.x <= 0 && !t.cur.off_x) { |
{ |
||||||
if (t.cur.y) { |
switch (a) { |
||||||
t.cur.y--; |
case (KEY_LEFT): |
||||||
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
if (t.cur.x <= 0 && !t.cur.off_x) { |
||||||
} |
if (t.cur.y) { |
||||||
} else t.cur.x--; |
t.cur.y--; |
||||||
break; |
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
||||||
|
} |
||||||
case (KEY_RIGHT): |
} else t.cur.x--; |
||||||
if (t.cur.x + t.cur.off_x >= rows.rw[t.cur.y + t.cur.off_y].size) { |
break; |
||||||
if (t.cur.y + t.cur.off_y < rows.rownum - 1) { |
|
||||||
t.cur.y++; |
case (KEY_RIGHT): |
||||||
if (t.cur.off_x) t.cur.off_x = 0; |
if (t.cur.x + t.cur.off_x >= rows.rw[t.cur.y + t.cur.off_y].size) { |
||||||
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
if (t.cur.y + t.cur.off_y < rows.rownum - 1) { |
||||||
} |
t.cur.y++; |
||||||
} else t.cur.x++; |
if (t.cur.off_x) t.cur.off_x = 0; |
||||||
break; |
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
||||||
|
} |
||||||
case (KEY_UP): |
} else t.cur.x++; |
||||||
if (t.cur.y + t.cur.off_y > 0) { |
break; |
||||||
if (t.cur.y) t.cur.y--; |
|
||||||
if (t.cur.x + t.cur.off_x > rows.rw[t.cur.y + t.cur.off_y].size) { |
case (KEY_UP): |
||||||
if (t.cur.off_x) t.cur.off_x = 0; |
if (t.cur.y + t.cur.off_y > 0) { |
||||||
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
if (t.cur.y) t.cur.y--; |
||||||
} |
if (t.cur.x + t.cur.off_x > rows.rw[t.cur.y + t.cur.off_y].size) { |
||||||
} |
if (t.cur.off_x) t.cur.off_x = 0; |
||||||
break; |
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
||||||
|
} |
||||||
case (KEY_DOWN): |
} |
||||||
if (t.cur.y + t.cur.off_y < rows.rownum - 1) { |
break; |
||||||
t.cur.y++; |
|
||||||
if (t.cur.x + t.cur.off_x > rows.rw[t.cur.y + t.cur.off_y].size) { |
case (KEY_DOWN): |
||||||
if (t.cur.off_x) t.cur.off_x = 0; |
if (t.cur.y + t.cur.off_y < rows.rownum - 1) { |
||||||
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
t.cur.y++; |
||||||
} |
if (t.cur.x + t.cur.off_x > rows.rw[t.cur.y + t.cur.off_y].size) { |
||||||
} |
if (t.cur.off_x) t.cur.off_x = 0; |
||||||
break; |
t.cur.x = rows.rw[t.cur.y + t.cur.off_y].size; |
||||||
} |
} |
||||||
} |
} |
||||||
|
break; |
||||||
void updateScroll (void) |
} |
||||||
{ |
} |
||||||
/* Set y offset */ |
|
||||||
if (t.cur.y >= t.dim.y) { |
void updateScroll (void) |
||||||
if (t.cur.y == t.dim.y) t.cur.off_y++; |
{ |
||||||
else t.cur.off_y += t.cur.y - t.dim.y; |
/* Set y offset */ |
||||||
|
if (t.cur.y >= t.dim.y) { |
||||||
t.cur.y = t.dim.y - 1; |
if (t.cur.y == t.dim.y) t.cur.off_y++; |
||||||
|
else t.cur.off_y += t.cur.y - t.dim.y; |
||||||
} else if (t.cur.y <= 0 && t.cur.off_y > 0) { |
|
||||||
t.cur.off_y--; |
t.cur.y = t.dim.y - 1; |
||||||
t.cur.y = 0; |
|
||||||
} |
} else if (t.cur.y <= 0 && t.cur.off_y > 0) { |
||||||
|
t.cur.off_y--; |
||||||
/* Set x offeset */ |
t.cur.y = 0; |
||||||
if (t.cur.x >= t.dim.x) { |
} |
||||||
if (t.cur.x == t.dim.x) t.cur.off_x++; |
|
||||||
else t.cur.off_x += t.cur.x - t.dim.x; |
/* Set x offeset */ |
||||||
|
if (t.cur.x >= t.dim.x) { |
||||||
t.cur.x = t.dim.x; |
if (t.cur.x == t.dim.x) t.cur.off_x++; |
||||||
|
else t.cur.off_x += t.cur.x - t.dim.x; |
||||||
} else if (t.cur.x <= 0 && t.cur.off_x > 0) { |
|
||||||
t.cur.off_x--; |
t.cur.x = t.dim.x; |
||||||
t.cur.x = 0; |
|
||||||
} |
} else if (t.cur.x <= 0 && t.cur.off_x > 0) { |
||||||
/* convert the cursor from real to render */ |
t.cur.off_x--; |
||||||
int ln = t.cur.y + t.cur.off_y; |
t.cur.x = 0; |
||||||
t.cur.r_x = curRealToRender(&rows.rw[ln], t.cur.x); |
} |
||||||
} |
/* convert the cursor from real to render */ |
||||||
|
int ln = t.cur.y + t.cur.off_y; |
||||||
/*---------------------------------- scroll ------------------------------------*/ |
t.cur.r_x = curRealToRender(&rows.rw[ln], t.cur.x); |
||||||
|
} |
||||||
/*
|
|
||||||
void bufferFree (void) |
/*---------------------------------- scroll ------------------------------------*/ |
||||||
{ |
|
||||||
for (int i = 0; i < rows.rownum; i++) { |
/*
|
||||||
free(&rows.rw[i].chars); |
void bufferFree (void) |
||||||
free(&rows.rw[i].render); |
{ |
||||||
} |
for (int i = 0; i < rows.rownum; i++) { |
||||||
free(rows.rw); |
free(&rows.rw[i].chars); |
||||||
} |
free(&rows.rw[i].render); |
||||||
*/ |
} |
||||||
|
free(rows.rw); |
||||||
/* See whats under the cursor (memory) */ |
} |
||||||
int whatsThat (void) { |
*/ |
||||||
int ln = t.cur.y + t.cur.off_y; |
|
||||||
int c = rows.rw[ln].chars[t.cur.x + t.cur.off_x]; |
/* See whats under the cursor (memory) */ |
||||||
switch (c) { |
int whatsThat (void) { |
||||||
case ('\t'): |
int ln = t.cur.y + t.cur.off_y; |
||||||
return '^'; |
int c = rows.rw[ln].chars[t.cur.x + t.cur.off_x]; |
||||||
break; |
switch (c) { |
||||||
case (' '): |
case ('\t'): |
||||||
return '~'; |
return '^'; |
||||||
break; |
break; |
||||||
default: |
case (' '): |
||||||
return c; |
return '~'; |
||||||
break; |
break; |
||||||
} |
default: |
||||||
return 0; |
return c; |
||||||
} |
break; |
||||||
|
} |
||||||
/*--------------------------------- garbage ------------------------------------*/ |
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*--------------------------------- garbage ------------------------------------*/ |
||||||
|
|
||||||
|
void updateInfo (void) |
||||||
|
{ |
||||||
|
getmaxyx(stdscr, t.dim.y, t.dim.x); |
||||||
|
t.dim.y -= 1; |
||||||
|
t.dim.x -= t.pad + 1; |
||||||
|
} |
||||||
|
|
||||||
|
/*--------------------------------- testing ------------------------------------*/ |
Loading…
Reference in new issue