shithub: irc.myr

Download patch

ref: 71f316d5c286036f582ac8372170982262ecf4e7
parent: 555d5ccd00ee6906a346f63338a520c92a8e0e6f
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Aug 26 18:29:55 EDT 2017

Logging and scrolling!

--- a/irc.myr
+++ b/irc.myr
@@ -1,7 +1,7 @@
 use std
 use sys
 use bio
-use thread
+use date
 use termdraw
 use fileutil	/* for homedir() */
 
@@ -19,7 +19,7 @@
 	user	: byte[:]
 	nick	: byte[:]
 	input	: byte[:]
-	hist	: byte[:][:]
+	cmdhist	: byte[:][:]
 	histidx	: std.size
 ;;
 
@@ -44,6 +44,7 @@
 	users	: byte[:][:]
 	stale	: bool
 	gutter	: int
+	scroll	: int
 ;;
 
 type hist = union
@@ -149,7 +150,7 @@
 	var c, name
 
 	if args.len == 1
-		c = name2chan(srv, args[0])
+		c = name2chan(cli, srv, args[0])
 		match std.strfind(src, "!")
 		| `std.Some i:	name = src[:i]
 		| `std.None:	name = src
@@ -158,7 +159,7 @@
 		| `std.None:	std.slpush(&c.users, std.sldup(name))
 		| `std.Some _:	/* ignore */
 		;;
-		std.slpush(&c.hist, (std.now(), `Join std.sldup(name)))
+		puthist(cli, c, (std.now(), `Join std.sldup(name)))
 	;;
 }
 
@@ -166,7 +167,7 @@
 	var c
 
 	if args.len >= 3
-		c = name2chan(srv, args[1])
+		c = name2chan(cli, srv, args[1])
 		std.slfree(c.topic)
 		c.topic = std.sldup(args[2])
 	;;
@@ -175,7 +176,7 @@
 const recievemsg = {cli, srv, src, args
 	var c
 
-	c = name2chan(srv, args[0])
+	c = name2chan(cli, srv, args[0])
 	chanmsg(cli, c, src, args[1])
 }
 
@@ -185,7 +186,7 @@
 	if args.len != 4
 		-> void
 	;;
-	c = name2chan(srv, args[2])
+	c = name2chan(cli, srv, args[2])
 	for n : std.bysplit(args[3], " ")
 		n = std.strstrip(n)
 		match std.lsearch(c.users, n, std.strcmp)
@@ -205,7 +206,7 @@
 	std.fatal("missing srv for fd {}", fd)
 }
 
-const name2chan = {srv, chan
+const name2chan = {cli, srv, chan
 	var new
 
 	for c : srv.chan
@@ -213,11 +214,12 @@
 			-> c
 		;;
 	;;
-	new = mkchan(chan, "")
+	new = mkchan(cli, chan, "")
 	std.slpush(&srv.chan, new)
 	if srv.focus == -1
 		srv.focus = srv.chan.len - 1
 	;;
+	status(cli, new, "joined on {}\n", date.now("local"))
 	-> new
 }
 
@@ -255,11 +257,11 @@
 		.srv = [][:],
 		.user = std.sldup(user),
 		.nick = std.sldup(nick),
-		.self = mkchan("status", "status"),
 		.focus = -1,
 		.term = t,
 		.logdir = std.pathcat(home, ".irclogs")
 	])
+	cli.self = mkchan(cli, "status", "status")
 
 	path = std.pathcat(home, ".ircrc")
 	match bio.open(path, bio.Rd)
@@ -271,8 +273,6 @@
 	;;
 	std.slfree(path)
 
-	std.mkpath(cli.logdir)
-
 	-> cli
 }
 
@@ -287,9 +287,17 @@
 	])
 }
 
-const mkchan = {name, topic
+const mkchan = {cli, name, topic
+	var logpath, logfd
+
+	std.mkpath(cli.logdir)
+	logpath = std.pathcat(cli.logdir, name)
+	match std.openmode(logpath, std.Ordwr | std.Ocreat | std.Oappend, 0o666)
+	| `std.Ok fd:	logfd = fd
+	| `std.Err _:	logfd = -1
+	;;
 	-> std.mk([
-		.log = -1, /* FIXME: log to file */
+		.log = logfd,
 		.hist = [][:], /* FIXME: read back from log */
 		.name = std.sldup(name),
 		.topic = std.sldup(topic),
@@ -612,6 +620,8 @@
 	var s
 
 	match termdraw.event(cli.term)
+	| `termdraw.Winsz _:
+
 	| `termdraw.Kc '\n':
 		do(cli, cli.input)
 		done(cli)
@@ -632,16 +642,21 @@
 		std.slfree(cli.input)
 		cli.input = ""
 	| `termdraw.Kup:
+		if chan.scroll < curchan(cli).hist.len
+			curchan(cli).scroll++
+		;;
 	| `termdraw.Kdown:
-	| `termdraw.Winsz _:
+		if chan.scroll > 0
+			chan.scroll--
+		;;
 	| r:
 		s = std.fmt("{}", r)
-		std.slpush(&cli.self.hist, (std.now(), `Status s))
+		puthist(cli, cli.self, (std.now(), `Status s))
 	;;
 }
 
 const done = {cli
-	std.slpush(&cli.hist, cli.input)
+	std.slpush(&cli.cmdhist, cli.input)
 	cli.input = ""
 }
 
@@ -696,7 +711,7 @@
 	if dx <= c.gutter
 		-> void
 	;;
-	for (tm, h) : std.byreverse(c.hist)
+	for (tm, h) : std.byreverse(c.hist[:c.hist.len - c.scroll])
 		margin = 0
 		match h
 		| `Msg (m, ln):
@@ -727,7 +742,7 @@
 
 	x = x0
 	y = y0
-	for (tm, h) : c.hist[c.hist.len - count:]
+	for (tm, h) : c.hist[c.hist.len - c.scroll - count:]
 		match h
 		| `Msg (m, ln):
 			(x, y) = draw(t, m, x0, y, x1, y1)
@@ -817,11 +832,7 @@
 
 	ap = std.vastart(&args)
 	s = std.fmtv(fmt, &ap)
-	std.slpush(&chan.hist, (std.now(), `Status s))
-
-	if chan != curchan(cli)
-		chan.stale = true
-	;;
+	puthist(cli, chan, (std.now(), `Status s))
 }
 
 const curchan = {cli
@@ -910,11 +921,31 @@
 	| `std.Some i:	nick = std.sldup(sender[:i])
 	| `std.None:	nick = std.sldup(sender)
 	;;
-	std.slpush(&chan.hist, (std.now(), `Msg (nick, std.sldup(msg))))
+	puthist(cli, chan, (std.now(), `Msg (nick, std.sldup(msg))))
+}
+
+const puthist = {cli, chan, entry
+	var tm, date, contents
+
+	std.slpush(&chan.hist, entry)
+	(tm, contents) = entry
+	if chan.log != -1
+		date = date.mkinstant(tm, "local")
+		match contents
+		| `Msg (u, ln):	std.fput(chan.log, "{} {} >{}\n", date, u, ln)
+		| `Join user:	std.fput(chan.log, "{} #join {}\n", date, user)
+		| `Part user:	std.fput(chan.log, "{} #part {}\n", date, user)
+		| `Status msg:	std.fput(chan.log, "{} #status {}\n", date, msg)
+		;;
+	else
+		std.put("wat\n")
+	;;
+	if chan.scroll != 0
+		chan.scroll++
+	;;
 	if chan != curchan(cli)
 		chan.stale = true
 	;;
-
 }
 
 const writeall = {fd, buf
--