(require 'riece-options)
(require 'riece-biff)
(require 'riece-log)
(require 'riece)
(or (featurep 'overlay)
(ignore-errors (require 'overlay)))
(or (featurep 'flyspell)
(ignore-errors (require 'flyspell)))
(setq riece-alias-percent-hack-mask "*.net"
riece-biff-check-channels '("#sxemacs"
"#emchat"
"#xemacs")
riece-channel-buffer-mode t
riece-ctlseq-colors
'("white" "black" "blue" "green" "red" "brown"
"purple" "orange" "yellow" "lightgreen" "darkcyan"
"cyan" "lightblue" "HotPink" "grey35" "grey")
riece-default-channel-binding nil
riece-default-coding-system 'utf-8
riece-desktop-notify-always t
riece-gather-channel-modes t
riece-hide-list '(joins parts quits)
riece-ignore-discard-message nil
riece-keywords
'("Bastard" "EMchat" "eMoney" "Gnus" "LFS" "LinuxFromScratch"
"LineageOS" "Lineage" "Linux From Scratch" "Riece" "SteveYoungs"
"SXEmacs" "XEmacs" "Youngs" "Steve Youngs" "SYWriting"
"SY Writing" "Gaiman" "Neil Gaiman" "xwem")
riece-layout '"bottom-right"
riece-retry-with-new-nickname t
riece-server-alist
'(("roddenberry.freenode.net" :host "roddenberry.freenode.net")
("irc.sxemacs.org" :host "irc.sxemacs.org")
("irc.freenode.net" :host "irc.freenode.net")
("irc.au.freenode.net" :host "irc.au.freenode.net")
("irc.nac.net" :host "irc.nac.net")
("irc.efnet.org" :host "irc.efnet.org")
("irc.efnet.net" :host "irc.efnet.net"))
riece-user-agent 'emacs-riece-config
riece-user-list-buffer-mode t)
(riece-command-insinuate-addon 'riece-yank)
(riece-command-insinuate-addon 'riece-hangman)
(riece-command-insinuate-addon 'riece-keepalive)
(riece-command-insinuate-addon 'riece-shrink-buffer)
(riece-command-insinuate-addon 'riece-xfaceb)
(riece-command-insinuate-addon 'riece-button)
(riece-command-insinuate-addon 'riece-epg)
(riece-command-enable-addon 'riece-hangman)
(defvar riece-unread-channels)
(defun sy-riece-clear-unread-chans ()
"Get rid of the unread mark on all channels."
(interactive)
(let ((current riece-current-channel))
(setq riece-unread-channels nil)
(riece-switch-to-channel current)))
(defun sy-riece-relist-chans-clear-blanks ()
"Relist the channel buffer removing any blanks in the sequence.
When you part from a channel/user you are left with a gap in the
sequence of channel numbers in the channels buffer. This removes
those gaps."
(interactive)
(let ((current riece-current-channel))
(setq riece-current-channels
(remove-if #'null riece-current-channels))
(riece-switch-to-channel current)))
(defun sy-riece-command-memoserv (command)
"Send COMMAND, a string, to MEMOSERV.
With prefix arg, also /join."
(interactive "sMemoserv: ")
(when current-prefix-arg
(riece-command-join (list ["MemoServ" ""])))
(riece-send-string (format "MEMOSERV %s\r\n" command)))
(defun sy-riece-command-chanserv (command)
"Send COMMAND, a string, to CHANSERV.
With prefix arg, also /join."
(interactive "sChanserv: ")
(when current-prefix-arg
(riece-command-join (list ["ChanServ" ""])))
(riece-send-string (format "CHANSERV %s\r\n" command)))
(defun sy-riece-command-nickserv (command)
"Send COMMAND, a string, to NICKSERV.
With prefix arg, also /join."
(interactive "sNickserv: ")
(when current-prefix-arg
(riece-command-join (list ["NickServ" ""])))
(riece-send-string (format "NICKSERV %s\r\n" command)))
(defun sy-riece-command-seenserv (command)
"Send COMMAND, a string, to SEENSERV.
SeenServ doesn't actually exist anymore, so this sends `info nick' to
NickServ which gives us the same info.
With prefix arg, also /join."
(interactive "sLast saw who (nick): ")
(when current-prefix-arg
(riece-command-join (list ["NickServ" ""])))
(riece-send-string (format "NICKSERV info %s\r\n" command)))
(defun sy-riece-command-quick-op ()
"Request Ops from ChanServ in the current channel."
(interactive)
(let ((chan (riece-identity-prefix riece-current-channel)))
(sy-riece-command-chanserv (format "OP %s" chan))))
(defun sy-riece-command-mute-user (&optional user unmute)
"Set mode +q on USER, effectively muting them.
Optional prefix arg, UNMUTE to let them speak again."
(interactive "i\nP")
(let ((user (or user
(completing-read
"(Un)Mute user: "
(riece-with-server-buffer
(riece-identity-server riece-current-channel)
(riece-channel-get-users (riece-identity-prefix
riece-current-channel)))))))
(riece-send-string
(format "MODE %s %sq %s\r\n"
(riece-identity-prefix riece-current-channel)
(if (or unmute
current-prefix-arg)
"-"
"+")
user))))
(defun sy-riece-list-banned (channel)
"List the banned users on CHANNEL, current if omitted."
(interactive "P")
(let ((channel (if current-prefix-arg
(vector (read-string "Channel: ") "")
riece-current-channel)))
(riece-send-string
(format "MODE %s b\r\n" (riece-identity-prefix channel)))))
(defun sy-riece-command-ban-user (&optional user unban)
"Ban USER from current channel.
Optional prefix arg, UNBAN removes the ban."
(interactive "i\nP")
(let ((user (or user
(completing-read
"(Un)Ban user: "
(riece-with-server-buffer
(riece-identity-server riece-current-channel)
(riece-channel-get-users (riece-identity-prefix
riece-current-channel))))))
reason)
(if (or unban
current-prefix-arg)
(riece-send-string
(format "MODE %s -b %s\r\n"
(riece-identity-prefix riece-current-channel)
user))
(setq reason (read-string "Reason: " nil nil
"Need a reason? Look in a mirror!"))
(riece-send-string
(format "MODE %s +b %s\r\n"
(riece-identity-prefix riece-current-channel)
user))
(riece-command-kick user reason))))
(defun sy-riece-say-now-playing (&optional notice)
"Say into the current channel what mp3 is playing.
With non-nil optional prefix arg, NOTICE, send it as a notice."
(interactive "P")
(riece-command-send-message
(format "NP: %s" (mpd-now-playing))
(and current-prefix-arg
'notice)))
(defun sy-riece-say-all-purpose (&optional notice)
"Send the all-purpose answer to everything."
(interactive "P")
(riece-command-send-message "Adolf Hitler in fishnets"
(if current-prefix-arg
'notice
nil)))
(defun sy-riece-say-version (&optional notice)
"Say the version of Riece we are running.
With non-nil prefix arg, NOTICE, send as a notice."
(interactive "P")
(riece-command-send-message
(format "I'm using: %s" (riece-extended-version))
(if current-prefix-arg
'notice
nil)))
(defun sy-riece-send-form ()
"Sends a form and it's eval"
(interactive)
(let* ((form (read-string "sexp: "))
(value (eval (read form))))
(riece-command-send-message (format "%s => %s" form value)
(if current-prefix-arg
'notice
nil))))
(defun sy-make-rot13-translation-table ()
"Create a rot13 table."
(let ((i -1)
(table (make-string 256 0))
(a (char-to-int ?a))
(A (char-to-int ?A)))
(while (< (incf i) 256)
(aset table i i))
(concat
(substring table 0 A)
(substring table (+ A 13) (+ A 13 (- 26 13)))
(substring table A (+ A 13))
(substring table (+ A 26) a)
(substring table (+ a 13) (+ a 13 (- 26 13)))
(substring table a (+ a 13))
(substring table (+ a 26) 255))))
(defun sy-rot13-string (string)
"Convert TEXT to rot13-ese."
(let ((table (sy-make-rot13-translation-table)))
(with-temp-buffer
(insert string)
(translate-region (point-min) (point-max) table)
(buffer-string))))
(defun sy-riece-send-rot13 (text)
"Talk in rot13-ese."
(interactive "srot13: ")
(riece-command-send-message
(sy-rot13-string text)
(if current-prefix-arg
'notice
nil)))
(defun sy-morse-string (string)
"Return STRING in morse code."
(with-temp-buffer
(insert string)
(morse-region (point-min) (point-max))
(goto-char (point-min))
(while (re-search-forward "/" nil t)
(replace-match " "))
(buffer-string)))
(defun sy-riece-send-morse (text)
"Talk in morse code."
(interactive "sMorse: ")
(riece-command-send-message
(sy-morse-string text)
(if current-prefix-arg
'notice
nil)))
(autoload 'riece-command-ctcp-action "riece-ctcp" nil t)
(defun sy-riece-show-off ()
"Brag about how many channels/people we're talking to."
(interactive)
(sy-riece-relist-chans-clear-blanks)
(let* ((channels riece-current-channels)
(numchans (length channels))
(numppl 0)
currchan)
(while channels
(setq currchan (car channels))
(setq numppl (+ numppl
(length (riece-with-server-buffer
(riece-identity-server currchan)
(riece-channel-get-users
(riece-identity-prefix currchan))))))
(setq channels (cdr channels)))
(riece-command-ctcp-action
riece-current-channel
(format
"is in %d channels, talking to %d people :-P"
numchans numppl))))
(defun sy-riece-sxe-uptime ()
"Display as action SXEmacs uptime."
(interactive)
(let* ((ut (uptime))
(days (car ut))
(hours (cadr ut))
(minutes (caddr ut))
(seconds (cadddr ut)))
(riece-command-ctcp-action
riece-current-channel
(concat "-=[ SXEmacs Uptime: "
(unless (zerop days)
(if (eq days 1)
"1 day, "
(concat (number-to-string days) " days, ")))
(unless (zerop hours)
(if (eq hours 1)
"1 hour, "
(concat (number-to-string hours) " hours, ")))
(unless (zerop minutes)
(if (eq minutes 1)
"1 minute, "
(concat (number-to-string minutes) " minutes, ")))
(if (zerop seconds)
"and 0 seconds"
(if (eq seconds 1)
"and 1 second."
(concat "and "
(number-to-string seconds)
" seconds")))
" ]=-"))))
(defun sy-riece-reverse ()
".sdrawkcab kaepS"
(interactive)
(let ((str (read-string "Say backwards: ")))
(riece-command-send-message
(concat (nreverse (string-to-list str))) nil)))
(defun sy-riece-think ()
"Send a .oO0{ think balloon action }."
(interactive)
(let ((think (read-string "What are you thinking? ")))
(riece-command-ctcp-action
riece-current-channel
(format ".oO0{ %s }" think))))
(defun sy-riece-fuck-you (&optional upyours)
"For those occasions where... you know what I mean."
(interactive "P")
(let ((fuckyou "
_ _
|_| |_|
| | /^^^\\ | |
_| |_ (| \"o\" |) _| |_
_| | | | _ (_---_) _ | | | |_
| | | | |' | _| |_ | `| | | | |
| | / \\ | |
\\ / / /(. .)\\ \\ \\ /
\\ / / / | . | \\ \\ \\ /
\\ \\/ / ||Y|| \\ \\/ /
\\__/ || || \\__/
() ()
|| ||
ooO Ooo")
(upyours "
.-.
|U|
| |
| |
_| |_
| | | |-.
/| ` |
| | |
| |
\\ /
| |
| |")
(riece-yank-tick 0.1))
(with-temp-buffer
(if current-prefix-arg
(insert upyours)
(insert fuckyou))
(kill-region (point-min) (point-max)))
(riece-command-yank nil nil)))
(defun sy-riece-command-complete-user ()
"Like `riece-command-complete-user' but restrict to current chan.
This version of nick completion maintains the original case of the
nick being completed. The version in Riece downcases the completion
\(could be a bug\).
If the completion is being inserted at column zero, `: ' is appended,
otherwise ` ' is added.
The following is not yet implemented, but I'd also like to be able to
complete from the middle of a nick...
Nickname User Types Expands To
-------- ---------- ----------
MyNick nic<TAB> MyNick:<SPC>"
(interactive)
(let* ((completion-ignore-case t)
(table (riece-with-server-buffer
(riece-identity-server riece-current-channel)
(riece-channel-get-users (riece-identity-prefix
riece-current-channel))))
(current (or (current-word) ""))
(completion (try-completion current table))
(all (all-completions current table)))
(if (eq completion t)
nil
(if (null completion)
(message "Can't find completion for \"%s\"" current)
(if (equal current completion)
(with-output-to-temp-buffer "*Help*"
(display-completion-list all))
(re-search-forward "\\>" nil t)
(delete-region (point) (- (point) (length current)))
(if (eq (point) (point-at-bol))
(insert completion ": ")
(insert completion " ")))))))
(defvar riece-me:completion-time 3
"Time in seconds before completion list is reset.")
(defvar riece-me:*completion-timer* (make-itimer)
"Completion timer.")
(defvar riece-me:*completion-list* nil
"Completion list.")
(defvar sy-riece-nick-syntax-table
(let ((table (copy-syntax-table text-mode-syntax-table)))
(modify-syntax-entry ?~ "w " table)
(modify-syntax-entry ?` "w " table)
(modify-syntax-entry ?- "w " table)
(modify-syntax-entry ?_ "w " table)
(modify-syntax-entry ?+ "w " table)
(modify-syntax-entry ?{ "w " table)
(modify-syntax-entry ?[ "w " table)
(modify-syntax-entry ?} "w " table)
(modify-syntax-entry ?] "w " table)
(modify-syntax-entry ?\\ "w " table)
(modify-syntax-entry ?| "w " table)
(modify-syntax-entry ?: "w " table)
(modify-syntax-entry ?\; "w " table)
(modify-syntax-entry ?' "w " table)
(modify-syntax-entry ?< "w " table)
(modify-syntax-entry ?, "w " table)
(modify-syntax-entry ?> "w " table)
table)
"Syntax table used in funky nick cycling completion.")
(defun sy-riece-init-completion-timer ()
"Initialise the completion timer."
(let ((timer riece-me:*completion-timer*))
(set-itimer-function timer #'(lambda ()
(setq riece-me:*completion-list* nil)))
(set-itimer-value timer riece-me:completion-time)))
(add-hook 'riece-after-login-hook #'sy-riece-init-completion-timer)
(defsubst sy-riece-cycle-list (list &optional reverse)
"Return a list of head of LIST, and LIST rotated 1 place forward.
If optional argument, REVERSE is non-nil, rotate the list in the other
direction."
(let ((list (apply #'dllist list))
name)
(if reverse
(dllist-rrotate list)
(dllist-lrotate list))
(setq name (dllist-car list))
(list name (dllist-to-list list))))
(defsubst sy-riece-set-completion-timer ()
"(Re)set completion timer's value."
(let ((timer riece-me:*completion-timer*))
(and (itimerp timer)
(set-itimer-value timer riece-me:completion-time))))
(defun sy-riece-complete-user-backwards ()
"Complete nick, cycling backwards.
See `riece-me:command-complete-user'."
(interactive)
(riece-me:command-complete-user 'reverse))
(defun sy-riece-command-mode-hooks ()
"Add some nice stuff in Riece's command buffer."
(when (eq major-mode 'riece-command-mode)
(local-set-key [iso-left-tab] #'sy-riece-complete-user-backwards)
(local-set-key [(super next)] #'riece-command-user-list-scroll-up)
(local-set-key [(super prior)] #'riece-command-user-list-scroll-down)
(local-set-key [(hyper next)] #'riece-command-scroll-up)
(local-set-key [(hyper prior)] #'riece-command-scroll-down)
(and (featurep (and 'overlay 'flyspell))
(flyspell-mode 1))))
(add-hook 'riece-command-mode-hook #'sy-riece-command-mode-hooks)
(defun riece-me:command-complete-user (&optional reverse)
"Like `riece-command-complete-user' but restrict to current chan.
This completion does not pop up any completion buffers, instead it
cycles through the user names \"in-place\" with each successive TAB.
With non-nil optional argument, REVERSE, the cycling goes in the other
direction.
If the completion is being inserted at column zero, \": \" is appended,
otherwise \" \" is added. "
(interactive)
(unless riece-me:*completion-list*
(unless (itimer-live-p riece-me:*completion-timer*)
(sy-riece-set-completion-timer)
(activate-itimer riece-me:*completion-timer*))
(let* ((completion-ignore-case t)
(table (riece-with-server-buffer
(riece-identity-server riece-current-channel)
(riece-channel-get-users (riece-identity-prefix
riece-current-channel))))
(current (current-word))
(completion (try-completion current table))
(all (all-completions current table)))
(if (null completion)
(message "Can't find completion for \"%s\"" current)
(setq riece-me:*completion-list* all))))
(when riece-me:*completion-list*
(multiple-value-bind (completion newlist)
(sy-riece-cycle-list riece-me:*completion-list* reverse)
(setq riece-me:*completion-list* newlist)
(with-syntax-table sy-riece-nick-syntax-table
(unless (string= "" (current-word))
(backward-delete-word))
(insert completion)
(let ((nicksuffix " "))
(save-excursion
(backward-word)
(and (bolp)
(setq nicksuffix ": ")))
(insert nicksuffix)))
(sy-riece-set-completion-timer))))
(defalias 'riece-command-complete-user 'riece-me:command-complete-user)
(defun sy-riece-add-rem-biff-channel (&optional remove)
"Add the current channel to the list of channels for riece-biff.
With optional prefix arg, REMOVE, remove the current channel from the
biff list."
(interactive "P")
(if (or current-prefix-arg
remove)
(progn
(setq riece-biff-check-channels
(remove (riece-identity-prefix riece-current-channel)
riece-biff-check-channels))
(message "Channel: %s removed from riece-biff channel list."
(riece-identity-prefix riece-current-channel)))
(add-to-list 'riece-biff-check-channels
(riece-identity-prefix riece-current-channel))
(message "Channel: %s added to riece-biff channel list."
(riece-identity-prefix riece-current-channel))))
(defun sy-riece-get-sxemacs-topic-version ()
"Return the \"version\" section of #sxemacs topic."
(let* ((topic (riece-with-server-buffer
(riece-identity-server riece-current-channel)
(riece-channel-get-topic "#sxemacs")))
(ver (third (split-string-by-char topic ?\ ))))
ver))
(defun sy-riece-sxemacs-topic-version-update (&optional newver)
"*Updates the \"version\" section of #sxemacs topic with NEWVER.
With a prefix arg, prompt for the new version string."
(interactive "P")
(let* ((oldver (sy-riece-get-sxemacs-topic-version))
(gitver (substring (shell-command-to-string
"( cd ${SXEWD}; git describe master )")
0 -1))
(newver (or (and current-prefix-arg
(read-string "New Version: "
sxemacs-git-version nil
sxemacs-git-version))
gitver))
(chan (riece-identity-prefix riece-current-channel)))
(unless (string= chan "#sxemacs")
(error 'invalid-argument "Wrong channel" chan))
(riece-command-send-message
(format ",topic change 1 s/%s/%s/" oldver newver) nil)))
(define-key riece-command-map (kbd "C-c C") #'sy-riece-clear-unread-chans)
(define-key riece-command-map (kbd "C-c r")
#'sy-riece-relist-chans-clear-blanks)
(define-key riece-command-map (kbd "C-c m") #'sy-riece-command-mute-user)
(define-key riece-command-map (kbd "C-b") #'sy-riece-command-ban-user)
(define-key riece-command-map (kbd "C-o") #'sy-riece-command-quick-op)
(define-key riece-command-map (kbd "C-c n") #'sy-riece-say-now-playing)
(define-key riece-command-map (kbd "C-c V") #'sy-riece-say-version)
(define-key riece-command-map (kbd "C-c s") #'sy-riece-show-off)
(define-key riece-command-map (kbd "C-c f") #'sy-riece-fuck-you)
(define-key riece-command-map (kbd "C-c b") #'sy-riece-add-rem-biff-channel)
(define-key riece-command-map (kbd "C-c ?") #'sy-riece-think)
(define-key riece-command-map (kbd "C-c R") #'sy-riece-reverse)
(define-key riece-command-map (kbd "C-c T") #'sy-riece-sxemacs-topic-version-update)
(define-key riece-command-map (kbd "C-c U") #'sy-riece-sxe-uptime)
(define-key riece-command-map [a] #'sy-riece-say-all-purpose)
(defvar riece-frame nil
"Frame for Riece.")
(defun sy-riece (&optional ask)
"Run Riece in a new frame.
With non-nil optional prefix ASK Riece will prompt for a server to
connect to."
(interactive "P")
(let ((riece-server (if current-prefix-arg
nil
"irc.sxemacs.org")))
(setq riece-frame (new-frame '((name . "RieceFrame")
(width . 110))))
(select-frame riece-frame)
(call-interactively 'riece)
(focus-frame riece-frame)))
(defun sy-riece-exit-hook ()
(when (frame-live-p riece-frame)
(delete-frame riece-frame))
(setq riece-frame nil))
(add-hook 'riece-exit-hook #'sy-riece-exit-hook)
(defvar sy-riece-startup-channel-list
'("#sxemacs"
"#emchat"
"#xemacs"
"#emacs"
"#LineageOS"
"#lxqt"
"#zsh"
)
"List of channels to join after logging in and identifying to nickserv.")
(mapcar
#'(lambda (chan)
(if (string-match #r"#\(sxemacs\|emchat\)" chan)
(push (cons chan 'iso-8859-1) riece-channel-coding-system-alist)
(push (cons chan 'utf-8) riece-channel-coding-system-alist)))
sy-riece-startup-channel-list)
(defun sy-riece-login ()
(progn
(riece-send-string (format "PRIVMSG NickServ :identify %s\r\n"
(getenv "IRCPASSWD")))
(sleep-for 15))
(let ((channel-list sy-riece-startup-channel-list)
entry identity)
(while channel-list
(unless (listp (setq entry (car channel-list)))
(setq entry (list (car channel-list))))
(if (equal (riece-identity-server
(setq identity (riece-parse-identity (car entry))))
riece-server-name)
(riece-command-join-channel identity (nth 1 entry)))
(setq channel-list (cdr channel-list))))
(riece-send-string "PRIVMSG ChanServ :op #sxemacs\r\n")
(riece-send-string "PRIVMSG ChanServ :op #emchat\r\n")
(riece-send-string "PRIVMSG ChanServ :op #xemacs\r\n")
(riece-send-string
(format "PRIVMSG SXEbot :identify SteveYoungs %s\r\n"
(getenv "BOTPASSWD"))))
(add-hook 'riece-after-login-hook #'sy-riece-login)
(defun sy-riece-cleanup-login ()
(interactive)
(let ((metachans
#r".*\.freenode\.net\|\(Chan\|Nick\|Memo\|Seen\)Serv\|SXEbot\|freenode-connect"))
(mapcar
#'(lambda (chan-vect)
(mapcar
#'(lambda (chan)
(and (string-match metachans chan)
(riece-part-channel chan-vect)))
chan-vect))
riece-current-channels)
(sy-riece-relist-chans-clear-blanks)
(riece-command-switch-to-channel-by-number 1)))
(define-key riece-command-map (kbd "C-c l") 'sy-riece-cleanup-login)
(defun sy-riece-check-command-buffer ()
(and (get-buffer-window (or riece-command-buffer "*Command*"))
(riece-biff-clear)))
(defadvice switch-to-buffer (after riece-update (&rest args) activate)
"After switching buffers, check to see if riece-biff should be cleared.
The riece-biff modeline indicator will only be cleared if
`riece-command-buffer' is visible in the selected frame."
(sy-riece-check-command-buffer))
(add-hook 'select-frame-hook #'sy-riece-check-command-buffer)
(defun sy-switch-to-riece ()
"I use this to switch to Riece when I'm on a tty."
(interactive)
(when (buffer-live-p riece-command-buffer)
(pop-to-buffer riece-command-buffer)
(riece-command-configure-windows)))
(define-key global-tty-map [(control ?c) ?r] #'sy-switch-to-riece)
(message "Riece settings loaded successfully")
Copyright © 2020 Steve Youngs
Verbatim copying and distribution is permitted in any medium,
providing this notice is preserved.
Last modified: Wed Apr 15 18:15:57 AEST 2020