Compare commits

..

4 Commits

116
editor.c
View File

@@ -5,8 +5,13 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h>
#define ctrl(x) ((x) & 0x1f)
int index_to_start = 0; int index_to_start = 0;
WINDOW* mainwin;
WINDOW* statusbar;
typedef struct Buffer_struct Buffer; typedef struct Buffer_struct Buffer;
struct Buffer_struct { struct Buffer_struct {
@@ -58,13 +63,20 @@ void buffer_insert(char ch, Buffer* buffer) {
} }
} }
void buffer_delete(Buffer* buffer) { void buffer_delete_front(Buffer* buffer) {
if (buffer->start != buffer->text) { if (buffer->start != buffer->text) {
buffer->start--; buffer->start--;
buffer->gap_size++; buffer->gap_size++;
} }
} }
void buffer_delete_back(Buffer* buffer) {
if (buffer->end != buffer->text + buffer->size) {
buffer->end++;
buffer->gap_size++;
}
}
void buffer_right(Buffer* buffer) { void buffer_right(Buffer* buffer) {
if (buffer->end != buffer->text + buffer->size) { if (buffer->end != buffer->text + buffer->size) {
char c = *(buffer->end); char c = *(buffer->end);
@@ -94,6 +106,10 @@ void scroll_page_down_handler(Buffer* buffer) {
} }
void page_down_handler(Buffer* buffer) { void page_down_handler(Buffer* buffer) {
if ((getcury(mainwin) + 1) == getmaxy(mainwin)) {
scroll_page_down_handler(buffer);
}
buffer_right(buffer); /* I must advance the cursor at least buffer_right(buffer); /* I must advance the cursor at least
once, so this hardcoded statement is fine. */ once, so this hardcoded statement is fine. */
@@ -102,10 +118,6 @@ void page_down_handler(Buffer* buffer) {
buffer_right(buffer); buffer_right(buffer);
} }
if ((getcury(stdscr) + 1) == getmaxy(stdscr)) {
scroll_page_down_handler(buffer);
}
/* You would think that I need to call 'buffer_right' once /* You would think that I need to call 'buffer_right' once
more, to advance the cursor onto the next line. In fact, if more, to advance the cursor onto the next line. In fact, if
you think about it, the place where the cursor (the rectangle) you think about it, the place where the cursor (the rectangle)
@@ -140,28 +152,61 @@ void page_up_handler(Buffer* buffer) {
} }
if ((getcury(stdscr) == 0) && (index_to_start > 0)) { if ((getcury(mainwin) == 0) && (index_to_start > 0)) {
scroll_page_up_handler(buffer); scroll_page_up_handler(buffer);
} }
} }
int is_file(char* path) {
struct stat st;
if (stat(path, &st) < 0) {
return -1;
}
return S_ISREG(st.st_mode);
}
void save_text_helper(Buffer* buffer,char* filename) {
FILE* file = fopen(filename,"w");
int i = 0;
while (i < buffer->size) {
if ((buffer->start - buffer->text) == i) { /* If we have encountered
the start of the gap */
i += buffer->gap_size;
}
if (i >= buffer->size) {
break;
}
fputc(*(buffer->text + i),file);
i++;
}
}
void init_curses() { void init_curses() {
initscr(); initscr();
mainwin = newwin(getmaxy(stdscr)-1,getmaxx(stdscr),0,0);
statusbar = newwin(1,getmaxx(stdscr),getmaxy(stdscr)-1,0);
wattrset(statusbar,A_REVERSE);
mvwhline(statusbar,0,0,' ',getmaxx(statusbar));
mvwprintw(statusbar,0,0,"Welcome to Editor!");
wrefresh(statusbar);
noecho(); noecho();
keypad(stdscr,TRUE); keypad(stdscr,TRUE);
cbreak(); keypad(mainwin,TRUE);
raw();
// scrollok(stdscr,TRUE); // scrollok(stdscr,TRUE);
} }
void sigint_handler(int dummy) { void end_ncurses() {
endwin(); endwin();
exit(130); exit(130);
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
signal(SIGINT,sigint_handler);
Buffer* buffer = new_buffer(10); Buffer* buffer = new_buffer(10);
FILE* logfile = fopen("logfile.txt","w"); FILE* logfile = fopen("logfile.txt","w");
@@ -175,14 +220,10 @@ int main(int argc, char** argv) {
num_of_chars++; num_of_chars++;
} }
} else { while (num_of_chars > 0) {
printf("File does not exist.\n"); buffer_left(buffer);
return -10; num_of_chars--;
} }
while (num_of_chars > 0) {
buffer_left(buffer);
num_of_chars--;
} }
} }
@@ -191,7 +232,7 @@ int main(int argc, char** argv) {
int y, x; int y, x;
while (true) { while (true) {
clear(); wclear(mainwin);
int i=index_to_start; int i=index_to_start;
if ((buffer->start != buffer->text) || (buffer->gap_size != buffer->size)) { /* We don't want to print the string, if the if ((buffer->start != buffer->text) || (buffer->gap_size != buffer->size)) { /* We don't want to print the string, if the
@@ -200,32 +241,38 @@ int main(int argc, char** argv) {
while (i < buffer->size) { while (i < buffer->size) {
if ((buffer->start - buffer->text) == i) { /* If we have encountered if ((buffer->start - buffer->text) == i) { /* If we have encountered
the start of the gap */ the start of the gap */
getyx(stdscr,y,x); getyx(mainwin,y,x);
i += buffer->gap_size; i += buffer->gap_size;
} }
if (i >= buffer->size) { if (i >= buffer->size) {
break; break;
} }
addch(*(buffer->text + i)); waddch(mainwin,*(buffer->text + i));
i++; i++;
fprintf(logfile,"At line %d of %d\n",getcury(stdscr),getmaxy(stdscr)); fprintf(logfile,"At line %d of %d\n",getcury(mainwin),getmaxy(mainwin));
if (*(buffer->text + i) == '\n' && ((getcury(stdscr) + 1) == getmaxy(stdscr))) { if (*(buffer->text + i) == '\n' && ((getcury(mainwin) + 1) == getmaxy(mainwin))) {
fprintf(logfile,"Read newline\n"); fprintf(logfile,"Read newline\n");
break; break;
} }
} }
move(y,x); wmove(mainwin,y,x);
wrefresh(mainwin);
} }
ch = getch(); ch = wgetch(mainwin);
switch(ch) { switch(ch) {
case KEY_BACKSPACE: case KEY_BACKSPACE:
buffer_delete(buffer); buffer_delete_front(buffer);
break;
case KEY_DC:
buffer_delete_back(buffer);
break; break;
case KEY_LEFT: case KEY_LEFT:
@@ -246,19 +293,32 @@ int main(int argc, char** argv) {
break; break;
case KEY_NPAGE: case KEY_NPAGE:
page_down_handler(buffer); page_down_handler(buffer);
break; break;
case KEY_PPAGE: case KEY_PPAGE:
page_up_handler(buffer); page_up_handler(buffer);
break; break;
case ctrl(KEY_NPAGE):
abort();
case ctrl('s'):
if (argc == 2) {
save_text_helper(buffer,argv[1]);
} else if (argc == 1) {
save_text_helper(buffer,NULL);
}
break;
case ctrl('c'):
end_ncurses();
break;
default: default:
buffer_insert(ch,buffer); buffer_insert(ch,buffer);
} }
continue_while_loop:
} }
endwin(); endwin();