Skip to content

Instantly share code, notes, and snippets.

@sasq64
Created June 28, 2017 14:04
Show Gist options
  • Select an option

  • Save sasq64/1bbb6ec3ab4f1d0fa7dd496658a561b8 to your computer and use it in GitHub Desktop.

Select an option

Save sasq64/1bbb6ec3ab4f1d0fa7dd496658a561b8 to your computer and use it in GitHub Desktop.
import std.stdio;
import std.conv;
import std.exception;
import diesel;
import ansi;
import textscreen;
import std.string;
alias toz = std.string.toStringz;
string which(string cmd, string path = null)
{
import std.c.stdlib : getenv;
import std.path : buildPath;
import std.file : exists;
import std.algorithm.iteration : splitter;
if(!path)
path = to!string(getenv("PATH"));
foreach(d ; splitter(path, ":"))
{
auto p = buildPath(d, cmd);
if(exists(p))
return p;
}
return null;
}
unittest {
import std.string : indexOf;
assert(which("ls").indexOf("bin") > 0);
}
import core.sys.posix.termios;
extern(C) void cfmakeraw(termios *termios_p);
void setRaw(int fd)
{
termios ostate;
termios nstate;
tcgetattr(fd, &nstate);
cfmakeraw(&nstate);
tcsetattr(fd, TCSADRAIN, &nstate);
//
// tcsetattr(f.fileno, TCSADRAIN, &ostate);
// return to original mode
}
struct winsize
{
ushort ws_row; /* rows, in characters */
ushort ws_col; /* columns, in characters */
ushort ws_xpixel; /* horizontal size, pixels */
ushort ws_ypixel; /* vertical size, pixels */
};
T tox(T, S)(S s) if(is(T == char**)) {
import core.stdc.stdlib;
char** argv = cast(char**) malloc((char*).sizeof * (s.length + 1));
foreach(i, arg; s) {
argv[i] = cast(char*) malloc(arg.length + 1);
argv[i][0 .. arg.length] = arg[];
argv[i][arg.length] = 0;
}
argv[s.length] = null;
return argv;
}
import core.sys.posix.unistd;
extern(C) pid_t forkpty(int *amaster, char *name, termios *termp, winsize *winp);
struct PtyFile
{
this(int fd)
{
this.fd = fd;
}
PtyFile blocking(bool on)
{
import core.sys.posix.fcntl;
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, (!on) ? flags | O_NONBLOCK : flags & ~O_NONBLOCK);
return this;
}
PtyFile nonBlocking()
{
return blocking(false);
}
void write(T)(T[] data) {
writefln("Write %d %s", data.length, T.stringof);
long rc = core.sys.posix.unistd.write(fd, data.ptr, data.length);
}
long read(T)(T[] data) {
long rc = core.sys.posix.unistd.read(fd, data.ptr, data.length);
return rc;
}
int fd;
}
const int PENDIN = 0x20000000;
const int ECHOCTL = 0x00000040;
const int ECHOKE = 0x00000001;
const int OXTABS = 0x00000004;
const int IUTF8 = 0x00004000;
PtyFile launch(string[] args)
{
import core.sys.posix.signal;
import core.sys.posix.sys.wait;
import core.sys.posix.stdlib;
winsize ws = winsize(24, 80, 512, 640);
termios tp;
int master;
char[128] name;
writeln(args);
extern(C) nothrow static @nogc
void childdead(int) {
try {
puts("CHILD DIED\n");
//writeln("Child died");
} catch(Error e) {}
wait(null);
}
signal(SIGCHLD, &childdead);
tcgetattr(0, &tp);
tp.c_lflag |= (ECHO | ECHOK | ECHOE);
tp.c_lflag |= (ICANON | ISIG | IEXTEN | ECHO);
tp.c_lflag |= (ECHOKE | ECHOCTL | PENDIN);
tp.c_iflag |= IUTF8;
tp.c_iflag &= ~IXON;
tp.c_oflag &= ~OXTABS;
tp.c_cflag |= CS8;
tp.c_cflag &= ~PARENB;
int rc = forkpty(&master, name.ptr, &tp, &ws);
if(rc == 0) {
// In child process
import core.stdc.stdlib;
setenv("TERM", "xterm", 1);
auto argv = tox!(char**)(args);
core.sys.posix.unistd.execv(argv[0], argv);
}
auto f = PtyFile(master);
f.nonBlocking();
return f;
}
void main(string[] args)
{
if(args.length < 2)
return;
auto cmd = which(args[1]);
writeln(cmd);
auto tty = launch([cmd] ~ args[2..$]);
auto screen = new TextScreen(80, 24);
auto as = ScreenParser.create("ansi", tty, screen);
init_video();
auto win = Window(80*8, 24*8);
auto font = new Font("unscii-8-fantasy.ttf", 16);
ubyte[] x = [0x1b, '[', 'B'];
win.onKey(win.KEY_ESC, { writeln("AAAH"); tty.write([cast(char)0x1b]); });
//win.onKey(win.KEY_CR, { writeln("C"); tty.rawWrite(x"0d"); });
win.onKey(win.KEY_DOWN, {
writeln(x);
tty.blocking(true);
tty.write(x);
tty.blocking(false);
});
win.onKey(win.KEY_UP, { writeln("U"); tty.write(x"1B" ~ "[A"); });
win.onKeyDefault((int c){ writeln("d");
char[] b = [ cast(char)c ];
tty.write(b);
});
win.runLoop({
for(int i=0; i<10; i++)
as.update();
screen.foreachString((int x, int y, string txt, uint fg, uint bg) {
font.renderText(x*8, y*8, txt, 0xffffff, bg);
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment