summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--buffer.cpp27
-rw-r--r--client.cpp79
-rw-r--r--jet.cpp142
-rw-r--r--jet2.cpp127
-rw-r--r--point.cpp95
-rw-r--r--todo.txt1
-rw-r--r--unicode.txt1
8 files changed, 310 insertions, 164 deletions
diff --git a/Makefile b/Makefile
index 959032c..45a82a3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-FLAGS=-lcurses $(shell ncursesw6-config --cflags --libs)
+FLAGS=-ggdb -O0 -lcurses $(shell ncursesw6-config --cflags --libs)
jet: Makefile *.cpp
g++ $(FLAGS) jet.cpp -o jet
diff --git a/buffer.cpp b/buffer.cpp
index 9313380..d1762d0 100644
--- a/buffer.cpp
+++ b/buffer.cpp
@@ -1,21 +1,24 @@
struct Buffer {
const char *name;
- Point start;
- Point cursor;
+ Page *storage;
- Buffer(const char *name) : name(name), start(), cursor(start) {}
+ Buffer(const char *name) : name(name), storage(new Page()) {}
- void prev_line(int window_width) {
- cursor--;
- cursor.rseek('\n', window_width - 1);
+ void read(const char *file) {
+ FILE *f = fopen(file, "r");
+ char c;
+ Point p(storage, 0);
+ while ((c = fgetc(f)) != EOF) {
+ p.push(c);
+ }
+ fclose(f);
}
- void next_line(int window_width) {
- cursor.seek('\n', window_width);
- if (cursor.element() == '\n') {
- cursor++;
+ void write(const char *file) {
+ FILE *f = fopen(file, "w+");
+ for (Point p(storage, 0); !p.at_end(); p++) {
+ fputc(p.element(), f);
}
+ fclose(f);
}
-
};
-
diff --git a/client.cpp b/client.cpp
new file mode 100644
index 0000000..f99dc5d
--- /dev/null
+++ b/client.cpp
@@ -0,0 +1,79 @@
+#define MAX_ARGS 16
+#define pos(x, y) (x) + (y) * window_w
+
+struct ArgList {
+ int len, cap;
+ int *args;
+
+ ArgList(int cap) : len(0), cap(cap) {
+ args = new int[cap];
+ for (int i = 0; i < cap; args[i++] = 0);
+ }
+ ~ArgList() { delete[] args; }
+
+ int pop() {
+ return args[--len];
+ }
+
+ void push(int value) {
+ args[len++] = value;
+ }
+
+};
+
+struct Client {
+ int sockfd;
+ Point cursor;
+ Point window_start;
+ ArgList args;
+
+ Client(const Buffer &b) :
+ cursor(b.storage, 0),
+ window_start(cursor),
+ args(MAX_ARGS)
+ {}
+
+ void show() {
+ int window_h = args.pop();
+ int window_w = args.pop();
+ char *view = new char[window_w * window_h];
+
+ Point window_end(window_start);
+ for (int i = 0; i < window_h; i++) {
+ for (int j = 0; j < window_w; j++) {
+ if (window_end == cursor) {
+ view[pos(j, i)] = '$';
+ } else {
+ view[pos(j, i)] = window_end.element();
+ }
+ if (window_end.element() == '\n') {
+ for (int k = j + 1; k < window_w; k++) {
+ view[pos(k, i)] = 0;
+ }
+ j = window_w;
+ } else if (window_end.element() == '\t') {
+ for (int k = j + 1; k < j + 8; k++) {
+ view[pos(k, i)] = 0;
+ }
+ j = j + 7;
+ }
+ window_end++;
+ }
+ }
+
+ write(sockfd, view, window_w * window_h);
+ delete[] view;
+ }
+
+ void move() {
+ int target = args.pop();
+ while (target > 0) {
+ cursor++;
+ target--;
+ }
+ while (target < 0) {
+ cursor--;
+ target++;
+ }
+ }
+};
diff --git a/jet.cpp b/jet.cpp
index b11744a..dd70f13 100644
--- a/jet.cpp
+++ b/jet.cpp
@@ -1,103 +1,81 @@
#include <stdlib.h>
#include <stdio.h>
-#include <assert.h>
-#include <locale.h>
-#include <curses.h>
-#define PAGE_SIZE 4096
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <sys/epoll.h>
+
#include "page.cpp"
#include "point.cpp"
#include "buffer.cpp"
+#include "client.cpp"
-#define NORMAL_MODE 0
-#define INSERT_MODE 1
-
-int main(int argc, char *argv[]) {
- setlocale(LC_ALL, "");
- initscr();
- cbreak();
- noecho();
- intrflush(stdscr, FALSE);
- keypad(stdscr, TRUE);
+#define PORT 6969
+#define MAX_COMMAND_SIZE 128
+#define MAX_EVENTS 10
- Buffer buffer("test");
- Point window_start(buffer.start);
+int create_listener() {
+ int s = socket(AF_INET, SOCK_STREAM, 0);
+ sockaddr_in addr = { AF_INET, htons(PORT), htonl(INADDR_LOOPBACK)};
+ int opt = 1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
+ bind(s, (sockaddr *) &addr, sizeof(sockaddr_in));
+ listen(s, MAX_EVENTS);
+ return s;
+}
- if (argc > 1) {
- FILE *f = fopen(argv[1], "r");
- char c;
- while ((c = fgetc(f)) != EOF) {
- buffer.cursor.push(c);
+void parse_command(char *command, Client *client) {
+ char *token = strtok(command, " \n");
+ while (token) {
+ if (strcmp(token, "show") == 0) {
+ client->show();
+ } else if (strcmp(token, "move") == 0) {
+ client->move();
+ } else {
+ client->args.push(atoi(token));
}
- buffer.cursor = buffer.start;
- fclose(f);
+ token = strtok(0, " \n");
}
+}
- int window_height, window_width;
- getmaxyx(stdscr, window_height, window_width);
+int main() {
+ Buffer scratch("scratch");
+ scratch.read("LICENSE");
- int mode = NORMAL_MODE;
+ int listener = create_listener();
+ int epollfd = epoll_create1(0);
+ epoll_event events[MAX_EVENTS];
+ epoll_event ev;
+ ev.events = EPOLLIN;
+ ev.data.fd = listener;
+ epoll_ctl(epollfd, EPOLL_CTL_ADD, listener, &ev);
- int quit = 0;
- while (!quit) {
- clear();
+ Client *clients[1024] = {};
- int x = -1, y = -1;
- Point window_end(window_start);
- while (!window_end.at_end() && getcury(stdscr) < window_height - 1) {
- if (window_end == buffer.cursor) {
- getyx(stdscr, y, x);
- }
- printw("%lc", window_end.element());
- window_end++;
- }
- printw("%d", buffer.cursor.index);
- if (x > -1 && y > -1) {
- move(y, x);
- }
+ for (;;) {
+ int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
- int input = getch();
- if (byte_type(input) == 1) {
- if (mode == NORMAL_MODE) {
- switch (input) {
- case '':
- quit = 1;
- break;
- case 'i':
- mode = INSERT_MODE;
- break;
- case 'k':
- buffer.prev_line(window_width);
- break;
- case 'j':
- buffer.next_line(window_width);
- break;
- case 'h':
- buffer.cursor--;
- break;
- case 'l':
- buffer.cursor++;
- break;
- }
+ for (int i = 0; i < nfds; i++) {
+ if (events[i].data.fd == listener) {
+ int clientfd = accept(listener, 0, 0);
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.fd = clientfd;
+ Client *c = new Client(scratch);
+ c->sockfd = clientfd;
+ clients[clientfd] = c;
+ epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ev);
} else {
- switch (input) {
- case '':
- mode = NORMAL_MODE;
- break;
- case KEY_BACKSPACE:
- buffer.cursor.pop();
- break;
- default:
- buffer.cursor.push(input);
- }
- }
- } else {
- buffer.cursor.push(input);
- for (int i = 0; i < byte_type(input) - 1; i++) {
- buffer.cursor.push(getch());
+ char command[MAX_COMMAND_SIZE] = {};
+ int clientfd = events[i].data.fd;
+ read(clientfd, command, MAX_COMMAND_SIZE - 1);
+ parse_command(command, clients[clientfd]);
}
}
}
- endwin();
- return 0;
+ close(listener);
}
diff --git a/jet2.cpp b/jet2.cpp
new file mode 100644
index 0000000..c00042a
--- /dev/null
+++ b/jet2.cpp
@@ -0,0 +1,127 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <locale.h>
+#include <curses.h>
+#include "page.cpp"
+#include "point.cpp"
+#include "buffer.cpp"
+
+#define NORMAL_MODE 0
+#define INSERT_MODE 1
+#define pos(x, y) (x) + (y) * window_width
+
+int main(int argc, char *argv[]) {
+ initscr();
+ cbreak();
+ noecho();
+ intrflush(stdscr, FALSE);
+ keypad(stdscr, TRUE);
+
+ if (argc > 1) {
+ buffer.read(argv[1]);
+ }
+
+ int window_height, window_width;
+ getmaxyx(stdscr, window_height, window_width);
+
+ int *view = new int[window_width * window_height];
+ for (int i = 0; i < window_width * window_height; view[i++] = 0);
+
+ int mode = NORMAL_MODE;
+
+ int quit = 0;
+ while (!quit) {
+ clear();
+
+ Point window_end(window_start);
+ int x = -1, y = -1;
+ for (int i = 0; i < window_height; i++) {
+ for (int j = 0; j < window_width; j++) {
+ if (window_end == cursor) {
+ x = j;
+ y = i;
+ }
+ view[pos(j, i)] = window_end.element();
+ if (window_end.element() == '\n') {
+ for (int k = j + 1; k < window_width; k++) {
+ view[pos(k, i)] = 0;
+ }
+ j = window_width;
+ } else if (window_end.element() == '\t') {
+ for (int k = j + 1; k < j + 8; k++) {
+ view[pos(k, i)] = 0;
+ }
+ j = j + 7;
+ }
+ window_end++;
+ }
+ }
+ for (int i = 0; i < window_width * window_height; i++) {
+ printw("%lc", view[i]);
+ }
+ if (x != -1 && y != -1) {
+ move(y, x);
+ }
+
+ int input = getch();
+ if (byte_type(input) == 1) {
+ if (mode == NORMAL_MODE) {
+ switch (input) {
+ case '':
+ quit = 1;
+ break;
+ case 'i':
+ mode = INSERT_MODE;
+ break;
+ case 'j':
+ for (int i = pos(x, y); i < pos(x + 1, y + 1); i++) {
+ if (view[i]) cursor++;
+ }
+ cursor--;
+ if (y + 1 >= window_height) {
+ window_start.seek('\n', window_width - 1);
+ window_start++;
+ }
+ break;
+ case 'k':
+ for (int i = pos(x, y); i > pos(x, y - 1); i--) {
+ if (view[i]) cursor--;
+ }
+ if (y - 1 <= 0) {
+ window_start--;
+ window_start.rseek('\n', window_width - 1);
+ }
+ break;
+ case 'h':
+ cursor--;
+ break;
+ case 'l':
+ cursor++;
+ break;
+ }
+ } else {
+ switch (input) {
+ case '':
+ mode = NORMAL_MODE;
+ break;
+ case KEY_BACKSPACE:
+ cursor.pop();
+ break;
+ default:
+ cursor.push(input);
+ }
+ }
+ } else {
+ cursor.push(input);
+ for (int i = 0; i < byte_type(input) - 1; i++) {
+ cursor.push(getch());
+ }
+ }
+ }
+
+ buffer.write(buffer.name);
+
+ endwin();
+ return 0;
+}
diff --git a/point.cpp b/point.cpp
index a331cb7..b0be8e9 100644
--- a/point.cpp
+++ b/point.cpp
@@ -2,26 +2,6 @@
#include <assert.h>
#include <stdbool.h>
-size_t byte_type(uint8_t byte) {
- if (byte & 1 << 7) {
- if (byte & 1 << 6) {
- if (byte & 1 << 5) {
- if (byte & 1 << 4) {
- return 4;
- } else {
- return 3;
- }
- } else {
- return 2;
- }
- } else {
- return 0;
- }
- } else {
- return 1;
- }
-}
-
struct Point {
Page *page;
uint16_t index;
@@ -76,32 +56,12 @@ struct Point {
}
}
- void pop_byte() {
- if (!at_start()) {
- align_gap();
- page->pop();
- move_backward();
- if (index == 0) {
- move_backward();
- }
- }
- if (page->is_empty()) {
- if (page->prev) {
- move_backward();
- delete page->next;
- } else if (page->next) {
- page->next->copy_to(page);
- delete page->next;
- index = 0;
- }
- }
- }
public:
- Point() : page(new Page()), index(0) {}
- Point(Page *page, uint16_t index) : page(page), index(index) {}
- Point(const Point& p) : page(p.page), index(p.index) {}
+ Point() : page(0), index(0) {}
+ Point(Page* page, uint16_t index) : page(page), index(index) {}
+ Point(const Point &p) : page(p.page), index(p.index) {}
bool operator==(Point p) {
return page == p.page && index == p.index;
@@ -120,30 +80,17 @@ struct Point {
}
void operator++(int) {
- do {
- if (index == page->element_count) move_forward();
- move_forward();
- } while (!byte_type(next_byte()));
+ if (index == page->element_count) move_forward();
+ move_forward();
}
void operator--(int) {
- do {
- move_backward();
- if (index == 0) move_backward();
- } while (!byte_type(next_byte()));
- }
-
- wchar_t element() {
- size_t type = byte_type(next_byte());
- wchar_t rune = next_byte() & (0xff >> type);
- Point iter(*this);
- for (size_t i = 1; i < type; i++) {
- rune <<= 6;
- iter.move_forward();
- if (iter.index == 0) iter.move_forward();
- rune |= (iter.next_byte() & 0x3f);
- }
- return rune;
+ move_backward();
+ if (index == 0) move_backward();
+ }
+
+ char element() {
+ return next_byte();
}
uint64_t seek(uint8_t c, uint64_t limit) {
@@ -187,10 +134,24 @@ struct Point {
}
void pop() {
- while (!byte_type(prev_byte())) {
- pop_byte();
+ if (!at_start()) {
+ align_gap();
+ page->pop();
+ move_backward();
+ if (index == 0) {
+ move_backward();
+ }
+ }
+ if (page->is_empty()) {
+ if (page->prev) {
+ move_backward();
+ delete page->next;
+ } else if (page->next) {
+ page->next->copy_to(page);
+ delete page->next;
+ index = 0;
+ }
}
- pop_byte();
}
};
diff --git a/todo.txt b/todo.txt
deleted file mode 100644
index ba70618..0000000
--- a/todo.txt
+++ /dev/null
@@ -1 +0,0 @@
-* free page correctly after no points point to it
diff --git a/unicode.txt b/unicode.txt
deleted file mode 100644
index 5bcdd50..0000000
--- a/unicode.txt
+++ /dev/null
@@ -1 +0,0 @@
-e$¢ह€한😁