#include <util.h>
#endif
+#define BUFFERSZ 16384
+
static View* EditView = NULL;
static int Pty_Fd = -1;
+char ReadBuf[BUFFERSZ+1] = {0};
+char ArgsBuf[BUFFERSZ+1] = {0};
+char InputBuf[BUFFERSZ+1] = {0};
+ssize_t ArgsPos = 0;
+ssize_t InputPos = 0;
+
+static enum {
+ READ_CHAR = 0,
+ READ_ESC,
+ READ_OSC,
+ READ_OSI,
+} State = READ_CHAR;
+
+static void read_char(char c)
+{
+ if (c == '\033')
+ {
+ State = READ_ESC;
+ }
+ else
+ {
+ InputBuf[InputPos++] = c;
+ InputBuf[InputPos] = '\0';
+ }
+}
+
+static void read_esc(char c)
+{
+ if (c == '[')
+ {
+ State = READ_OSI;
+ }
+ else
+ if (c == ']')
+ {
+ State = READ_OSC;
+ }
+ else
+ {
+ State = READ_CHAR;
+ }
+}
+
+static void read_osc(char c)
+{
+ if (c == '\a')
+ {
+ State = READ_CHAR;
+ if (ArgsBuf[0] == '7' && ArgsBuf[1] == ';')
+ {
+ chdir(&ArgsBuf[2]);
+ }
+ ArgsPos = 0;
+ ArgsBuf[0] = '\0';
+ }
+ else
+ {
+ ArgsBuf[ArgsPos++] = c;
+ ArgsBuf[ArgsPos] = '\0';
+ }
+}
+
+static void read_osi(char c)
+{
+ if (isalpha(c))
+ {
+ State = READ_CHAR;
+ }
+}
+
+static void (*Handlers[])(char c) = {
+ [READ_CHAR] = read_char,
+ [READ_ESC] = read_esc,
+ [READ_OSC] = read_osc,
+ [READ_OSI] = read_osi,
+};
+
static void putb(int byte)
{
struct termios tio = {0};
{
*((char*)(EditView->buffer.contents.gapstart-1)) = '*';
}
+ else
+ {
+ *((char*)(EditView->buffer.contents.gapstart-1)) = ' ';
+ EditView->buffer.point.beg = EditView->buffer.point.end;
+ }
}
- if (byte == '\n' && buf_inpoint(&(EditView->buffer), EditView->buffer.selection.end-1))
+ else if (byte == '\n' && buf_inpoint(&(EditView->buffer), EditView->buffer.selection.end-1))
{
/* get the input string and update the point */
char* str = buf_getsat(&(EditView->buffer), EditView->buffer.point.beg, EditView->buffer.point.end);
static void writedata(char* buf, long n)
{
- char data[16384];
- int p = 0;
- for (int i = 0; i < n; i++)
+ InputBuf[0] = '\0';
+ InputPos = 0;
+ for (long i = 0; i < n; i++)
{
- if (buf[i] == '\033')
- {
- }
- else
- {
- data[p++] = buf[i];
- data[p] = '\0';
- }
+ Handlers[State](buf[i]);
}
- view_putraw(EditView, data);
+ view_putraw(EditView, InputBuf);
EditView->sync_flags |= CURSOR;
}
static void xpty_read(Job* job)
{
- char buffer[16385];
- long nread = read(job->fd, buffer, sizeof(buffer)-1);
+ long nread = read(job->fd, ReadBuf, sizeof(ReadBuf)-1);
if (nread <= 0)
{
job->readfn = NULL;
}
else if (nread > 0)
{
- buffer[nread] = '\0';
+ ReadBuf[nread] = '\0';
/* swap the point and selection to perform the insert */
size_t start = EditView->buffer.point.beg;
EditView->buffer.point = sel;
/* insert the text */
- writedata(buffer, nread);
+ writedata(ReadBuf, nread);
/* adjust the original selection and swap it back */
nread = (EditView->buffer.point.end - start);
view->buffer.oninsert = putb;
view->buffer.point.beg = view->buffer.selection.end;
view->buffer.point.end = view->buffer.selection.end;
-// struct termios tio;
-// tcgetattr(Pty_Fd, &tio);
-// tio.c_lflag &= ~(ECHO | ECHONL);
-// tio.c_cc[ VMIN ] = 1;
-// tio.c_cc[ VTIME ] = 0;
-// tcsetattr(Pty_Fd, TCSANOW, &tio);
job_spawn(Pty_Fd, xpty_read, NULL, NULL);
}
}