LDFLAGS = -L/opt/X11/lib -lX11 -lXft
CFLAGS = --std=c99 -Wall -Wextra -I. -I/opt/X11/include -I/opt/local/include/freetype2 -I/usr/include/freetype2
-SRCS = xedit.c buf.c screen.c utf8.c
+SRCS = xedit.c buf.c screen.c utf8.c keyboard.c
OBJS = $(SRCS:.c=.o)
TESTSRCS = tests/tests.c tests/buf.c tests/utf8.c
TESTOBJS = $(TESTSRCS:.c=.o)
void buf_load(Buf* buf, char* path)
{
+ buf->insert_mode = true;
unsigned i = 0;
FILE* in = (!strcmp(path,"-") ? stdin : fopen(path, "rb"));
while (EOF != fpeekc(in)) {
buf_ins(buf, i++, r);
}
fclose(in);
+ buf->insert_mode = false;
}
void buf_initsz(Buf* buf, size_t sz)
void buf_del(Buf* buf, unsigned off)
{
+ if (!buf->insert_mode) return;
syncgap(buf, off);
buf->gapend++;
}
void buf_ins(Buf* buf, unsigned off, Rune rune)
{
+ if (!buf->insert_mode) return;
syncgap(buf, off);
*(buf->gapstart++) = rune;
}
#include <stdbool.h>
#include <string.h>
+/* UTF-8 Handling
+ *****************************************************************************/
+enum {
+ UTF_MAX = 6u, /* maximum number of bytes that make up a rune */
+ RUNE_SELF = 0x80, /* byte values larger than this are *not* ascii */
+ RUNE_ERR = 0xFFFD, /* rune value representing an error */
+ RUNE_MAX = 0x10FFFF, /* Maximum decodable rune value */
+ RUNE_EOF = EOF /* ruen value representing end of file */
+};
+
+/* Represents a unicode code point */
+typedef uint32_t Rune;
+
+size_t utf8encode(char str[UTF_MAX], Rune rune);
+bool utf8decode(Rune* rune, size_t* length, int byte);
+
/* Input Handling
*****************************************************************************/
/* key definitions */
MOUSE_WHEELDOWN
};
-/* UTF-8 Handling
- *****************************************************************************/
-enum {
- UTF_MAX = 6u, /* maximum number of bytes that make up a rune */
- RUNE_SELF = 0x80, /* byte values larger than this are *not* ascii */
- RUNE_ERR = 0xFFFD, /* rune value representing an error */
- RUNE_MAX = 0x10FFFF, /* Maximum decodable rune value */
- RUNE_EOF = EOF /* ruen value representing end of file */
-};
-
-/* Represents a unicode code point */
-typedef uint32_t Rune;
-
-size_t utf8encode(char str[UTF_MAX], Rune rune);
-bool utf8decode(Rune* rune, size_t* length, int byte);
+void handle_key(Rune key);
/* Buffer management functions
*****************************************************************************/
--- /dev/null
+#include "edit.h"
+
+extern Buf Buffer;
+extern unsigned CursorPos;
+
+static void special_keys(Rune key);
+static void control_keys(Rune key);
+
+void handle_key(Rune key) {
+ /* ignore invalid keys */
+ if (key == RUNE_ERR) return;
+ /* handle the special keys */
+ if (0xE000 <= key && key <= 0xF8FF)
+ special_keys(key);
+ /* Handle regular key */
+ else if (key < 0x20)
+ control_keys(key);
+ else if (Buffer.insert_mode)
+ buf_ins(&Buffer, CursorPos++, key);
+
+}
+
+static void special_keys(Rune key) {
+ switch (key) {
+ case KEY_F1: Buffer.insert_mode = !Buffer.insert_mode; break;
+ case KEY_F6: ColorBase = !ColorBase; break;
+ case KEY_LEFT: CursorPos = buf_byrune(&Buffer, CursorPos, -1); break;
+ case KEY_RIGHT: CursorPos = buf_byrune(&Buffer, CursorPos, 1); break;
+ case KEY_DOWN: CursorPos = buf_byline(&Buffer, CursorPos, 1); break;
+ case KEY_UP: CursorPos = buf_byline(&Buffer, CursorPos, -1); break;
+ case KEY_DELETE:
+ if (Buffer.insert_mode)
+ buf_del(&Buffer, CursorPos);
+ break;
+
+ }
+}
+
+static void control_keys(Rune key) {
+ switch (key) {
+ case KEY_ESCAPE: Buffer.insert_mode = false; break;
+ case KEY_BACKSPACE: buf_del(&Buffer, --CursorPos); break;
+ default: buf_ins(&Buffer, CursorPos++, key); break;
+ }
+}
#include "edit.h"
+Buf Buffer;
+unsigned CursorPos = 0;
+enum ColorScheme ColorBase = DEFAULT_COLORSCHEME;
struct {
Display* display;
Visual* visual;
XIC xic;
XIM xim;
} X;
-Buf Buffer;
-unsigned CursorPos = 0;
-enum ColorScheme ColorBase = DEFAULT_COLORSCHEME;
void die(char* m) {
fprintf(stderr, "dying, %s\n", m);
if (buf[0] == '\r') buf[0] = '\n';
for(int i = 0; i < 8 && !utf8decode(&rune, &len, buf[i]); i++);
}
- printf("key: %#x\n", rune);
/* translate the key code into a unicode codepoint */
switch (key) {
case XK_F1: return KEY_F1;
}
}
-static void handle_key(XEvent* e) {
- Rune key = getkey(e);
- /* Handle the key */
- switch (key) {
- case RUNE_ERR: break;
- case KEY_F1:
- Buffer.insert_mode = !Buffer.insert_mode;
- break;
-
- case KEY_F6:
- ColorBase = !ColorBase;
- break;
-
- case KEY_LEFT:
- CursorPos = buf_byrune(&Buffer, CursorPos, -1);
- break;
-
- case KEY_RIGHT:
- CursorPos = buf_byrune(&Buffer, CursorPos, 1);
- break;
-
- case KEY_DOWN:
- CursorPos = buf_byline(&Buffer, CursorPos, 1);
- break;
-
- case KEY_UP:
- CursorPos = buf_byline(&Buffer, CursorPos, -1);
- break;
-
- case KEY_ESCAPE:
- Buffer.insert_mode = false;
- break;
-
- case KEY_BACKSPACE:
- if (Buffer.insert_mode)
- buf_del(&Buffer, --CursorPos);
- break;
-
- case KEY_DELETE:
- if (Buffer.insert_mode)
- buf_del(&Buffer, CursorPos);
- break;
-
- default:
- if (Buffer.insert_mode)
- buf_ins(&Buffer, CursorPos++, key);
- break;
- }
-}
-
static void handle_mousebtn(XEvent* e) {
switch (e->xbutton.button) {
case Button1: /* Left Button */
case FocusIn: if (X.xic) XSetICFocus(X.xic); break;
case FocusOut: if (X.xic) XUnsetICFocus(X.xic); break;
case ButtonPress: handle_mousebtn(e); break;
- case KeyPress: handle_key(e); break;
+ case KeyPress: handle_key(getkey(e)); break;
case ConfigureNotify: // Resize the window
if (e->xconfigure.width != X.width || e->xconfigure.height != X.height) {
X.width = e->xconfigure.width;