ref: cc395f1b257d9e7ec575ef4b3f49bbdea06277f7
parent: 1883b6157dbc02a03e4a678aa0ecdf8bee211129
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Nov 11 08:42:51 EST 2017
Fixes and cleanups.
--- a/irc.myr
+++ b/irc.myr
@@ -29,6 +29,7 @@
;;
type server = struct
+ id : std.size
fd : std.fd
user : byte[:]
nick : byte[:]
@@ -136,7 +137,9 @@
| "376": srvmsg(irc, args)
| "NOTICE": srvmsg(irc, args)
| "332": topic(irc, srv, args)
- | "353": addnames(irc, srv, args)
+ | "353": addusers(irc, srv, args)
+ | "QUIT": deluser(irc, src)
+ | "PART": delchanuser(irc, srv, args)
| "366": shownames(irc, [][:])
| "PRIVMSG": recievemsg(irc, srv, src, args)
| "PING": send(irc, srv, "PONG :{}\r\n", args[0])@@ -189,7 +192,7 @@
chanmsg(irc, c, src, args[1])
}
-const addnames = {irc, srv, args+const addusers = {irc, srv, argsvar c
if args.len != 4
@@ -202,10 +205,39 @@
| `std.None: std.slpush(&c.users, std.sldup(n))
| `std.Some _: /* ignore */
;;
- c.gutter = std.max(c.gutter, n.len + 1)
+ c.gutter = std.max(c.gutter, n.len + 2)
;;
}
+const deluser = {irc, srv, user+ var nick
+
+ for c : srv.chan
+ match std.strfind(sender, "!")
+ | `std.Some i: nick = std.sldup(sender[:i])
+ | `std.None: nick = std.sldup(sender)
+ ;;
+ match std.lsearch(c.users, nick, std.strcmp)
+ | `std.None: /* ignore */
+ | `std.Some i: std.sldel(&c.users, i)
+ ;;
+ ;;
+}
+
+const delchanuser = {irc, src, args+ if args.len == 0
+ -> void
+ ;;
+ match std.strfind(sender, "!")
+ | `std.Some i: nick = std.sldup(sender[:i])
+ | `std.None: nick = std.sldup(sender)
+ ;;
+ match std.lsearch(c.users, nick, std.strcmp)
+ | `std.None: /* ignore */
+ | `std.Some i: std.sldel(&c.users, i)
+ ;;
+}
+
const fd2srv = {irc, fdfor s : irc.srv
if s.fd == fd
@@ -223,12 +255,13 @@
-> c
;;
;;
- new = mkchan(irc, chan, "")
+
+ new = mkchan(irc, srv, chan, "")
std.slpush(&srv.chan, new)
if srv.focus == -1
srv.focus = srv.chan.len - 1
;;
- status(irc, new, "joined on {}\n", date.now("local"))+ status(irc, new, "joined on {}", date.now("local"))-> new
}
@@ -307,7 +340,7 @@
])
}
-const mkchan = {irc, name, topic+const mkchan = {irc, srv, name, topicvar logpath, logfd
std.mkpath(irc.logdir)
@@ -369,6 +402,7 @@
| "help": help(irc, sp[1:])
| "nick": changenick(irc, sp[1:])
| "user": changeuser(irc, sp[1:])
+ | "srv": changeserver(irc, sp[1:])
| c: status(irc, irc.self, "unknown command: /{}", text);;
std.slfree(sp)
@@ -410,6 +444,17 @@
;;
}
+const changeserver = {irc, args+ if args.len != 1
+ status(irc, irc.self, "/nick: invalid args {j= }", args)+ -> void
+ ;;
+ match findsrv(irc, args[0])
+ | `std.Some s: irc.focus = s.id
+ | `std.None: status(irc, irc.self, "no server '{}", args[0])+ ;;
+}
+
const connect = {irc, argsvar ds, srv
@@ -435,6 +480,7 @@
| `std.Ok fd:
srv = mksrv(irc, fd, ds)
if handshake(irc, srv)
+ srv.id = irc.srv.len
std.slpush(&irc.srv, srv)
if irc.focus == -1
irc.focus = irc.srv.len - 1
@@ -523,11 +569,14 @@
if irc.srv.len == 0
-> void
;;
- if irc.focus < 0 || irc.focus >= irc.srv.len
- irc.focus = 0
- ;;
- while true
+ irc.chandirty = true
+ irc.cmddirty = true
+ for var i = 0; i < irc.srv.len; i++
+ if irc.focus < 0 || irc.focus >= irc.srv.len
+ irc.focus = 0
+ ;;
+
srv = irc.srv[irc.focus]
srv.focus += delta
if srv.focus < 0 || srv.focus >= srv.chan.len
@@ -538,7 +587,9 @@
irc.focus %= irc.srv.len
irc.srv[irc.focus].focus = 0
;;
- if srv.chan.len != 0
+ srv = irc.srv[irc.focus]
+ if srv.chan.len > 0
+ srv.chan[srv.focus].stale = false
break
;;
;;
@@ -553,6 +604,8 @@
else
srvidx = -1
idx = -1
+ irc.chandirty = true
+ irc.cmddirty = true
match std.strfind(irc.self.name, args[0])
| `std.None: /* ok */
| `std.Some i: idx = i
@@ -685,6 +738,9 @@
ln = getstr(irc.cmd)
do(irc, ln)
std.slfree(ln)
+ std.slfree(irc.cmd)
+ irc.cmd = [][:]
+ irc.off = 0
| `std.Some `termdraw.Ctrl 'n':
chancycle(irc, 1)
| `std.Some `termdraw.Ctrl 'p':
@@ -818,25 +874,28 @@
| `Msg (m, ln):
margin = c.gutter
width = termdraw.strwidth(t, ln)
- height += width / (dx - margin + 1) + 1
| `Join user:
- width = termdraw.strwidth(t, "#joined: ")
- width += termdraw.strwidth(t, user)
- height += width / (dx + 1) + 1
+ margin = termdraw.strwidth(t, "#joined: ")
+ width = termdraw.strwidth(t, user)
| `Part user:
- width = termdraw.strwidth(t, "#parted: ")
- width += termdraw.strwidth(t, user)
- height += width / (dx + 1) + 1
+ margin = termdraw.strwidth(t, "#parted: ")
+ width = termdraw.strwidth(t, user)
| `Status msg:
- width = termdraw.strwidth(t, "! ")
- width += termdraw.strwidth(t, msg)
- height += width / (dx + 1) + 1
+ margin = termdraw.strwidth(t, "! ")
+ width = termdraw.strwidth(t, msg)
;;
+ if dx - margin + 1 <= 0
+ -> void
+ ;;
+ height++
+ if width > 0
+ height += (width - 1) / (dx - margin)
+ ;;
count++
if height == dy
break
elif height > dy
- off = (dx - margin)*(height - dy - 1) + width % dx
+ off = (dx - margin)*(height - dy)
break
;;
;;
@@ -846,17 +905,18 @@
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)
+ x = std.clamp(x0 + c.gutter - termdraw.strwidth(t, m) - 3, 0, dx)
+ (x, y) = draw(t, m, x, y, x1, y1)
(x, y) = draw(t, ">", x0 + c.gutter - 2, y, x1, y1)
(x, y) = draw(t, ln[off:], x0 + c.gutter, y, x1, y1)
| `Join user:
(x, y) = draw(t, "#joined ", x0, y, x1, y1)
- (x, y) = draw(t, user, x, y, x1, y1)
+ (x, y) = draw(t, user[off:], x, y, x1, y1)
| `Part user:
(x, y) = draw(t, "#parted ", x0, y, x1, y1)
- (x, y) = draw(t, user, x, y0, y, y1)
+ (x, y) = draw(t, user[off:], x, y0, y, y1)
| `Status msg:
- (x, y) = draw(t, "! : ", x0, y, x1, y1)
+ (x, y) = draw(t, "! ", x0, y, x1, y1)
(x, y) = draw(t, msg[off:], x, y, x1, y1)
;;
y++
--
⑨