X-Git-Url: https://jxself.org/git/?p=8sync.git;a=blobdiff_plain;f=demos%2Firc.scm;h=eabc31d82b3baa44eb73f62db4df9ab55ea14d02;hp=a5e9ba4426fb6e9f1e5c5a0b0b8d558584a3f561;hb=d86e4ab5d19c62bd585239dd600aa2645b337c74;hpb=9c8d37765bca38ffe643434ca154999f8e602a6a diff --git a/demos/irc.scm b/demos/irc.scm index a5e9ba4..eabc31d 100755 --- a/demos/irc.scm +++ b/demos/irc.scm @@ -21,8 +21,10 @@ (use-modules (eightsync repl) (eightsync agenda) + (srfi srfi-9) (ice-9 getopt-long) (ice-9 format) + (ice-9 receive) (ice-9 q) (ice-9 match)) @@ -83,6 +85,14 @@ (eq? (string-ref str 0) #\:))) +(define-record-type + (make-irc-line prefix command params) + irc-line? + (prefix irc-line-prefix) + (command irc-line-command) + (params irc-line-params)) + + (define (parse-line line) (define (parse-params pre-params) ;; This is stupid and imperative but I can't wrap my brain around @@ -113,20 +123,69 @@ (((? startswith-colon? prefix) command pre-params ...) - (list prefix command - (parse-params2 pre-params))) + (make-irc-line prefix command + (parse-params pre-params))) ((command pre-params ...) - (list #f command (parse-params2 pre-params))))) + (make-irc-line #f command + (parse-params pre-params))))) +(define (strip-colon-if-necessary string) + (if (and (> (string-length string) 0) + (string-ref string 0)) + (substring/copy string 1) + string)) -(define (handle-line socket line my-username) - (match (string-split line #\space) - (("PING" rest ...) - (irc-display "PONG" socket) - (display "PONG'ed back ;)\n")) - (_ - (display line) - (newline)))) +;; @@: Not sure if this works in all cases, like what about in a non-privmsg one? +(define (irc-line-username irc-line) + (let* ((prefix-name (strip-colon-if-necessary (irc-line-prefix irc-line))) + (exclaim-index (string-index prefix-name #\!))) + (if exclaim-index + (substring/copy prefix-name 0 exclaim-index) + prefix-name))) + +(define (condense-privmsg-line line) + "Condense message line and do multiple value return of + (channel message is-action)" + (define (strip-last-char string) + (substring/copy string 0 (- (string-length string) 1))) + (let* ((channel-name (caar line)) + (rest-params (apply append (cdr line)))) + (match rest-params + (((or "\x01ACTION" ":\x01ACTION") middle-words ... (= strip-last-char last-word)) + (values channel-name + (string-join + (append middle-words (list last-word)) + " ") + #t)) + (((= strip-colon-if-necessary first-word) rest-message ...) + (values channel-name + (string-join (cons first-word rest-message) " ") + #f))))) + +(define (default-handle-privmsg my-name speaker + channel-name message is-action) + (if is-action + (format #t "~a emoted ~s in channel ~a\n" + speaker message channel-name) + (format #t "~a said ~s in channel ~a\n" + speaker message channel-name))) + +(define* (make-handle-line #:key + (handle-privmsg default-handle-privmsg)) + (define (handle-line socket line my-username) + (let ((parsed-line (parse-line line))) + (match (irc-line-command parsed-line) + ("PING" + (irc-display "PONG" socket)) + ("PRIVMSG" + (receive (channel-name message is-action) + (condense-privmsg-line (irc-line-params parsed-line)) + (let ((username (irc-line-username parsed-line))) + (handle-privmsg my-username username channel-name message is-action)))) + (_ + (display line) + (newline))))) + handle-line) (define (make-simple-irc-handler handle-line username) (let ((buffer '())) @@ -153,7 +212,7 @@ (inet-port default-irc-port) (handler (make-simple-irc-handler (lambda args - (apply handle-line args)) + (apply (make-handle-line) args)) username)) (channels '())) (dynamic-wind