From: Thomas W. <3....@gm...> - 2004-11-23 10:46:22
|
Hi, i wrote a small patch so that erc uses all the user modes provided bei the server's 005 message with PREFIX=(abc)!@#. I am new to elisp and to erc, but i think this might be useful (using erc is annoying without it for me). so pls have a look at it. Common subdirectories: erc/CVS and erc.new/CVS Common subdirectories: erc/debian and erc.new/debian Only in erc.new: erc-auto.el diff -ux '*.elc' -x '*~' erc/erc-backend.el erc.new/erc-backend.el --- erc/erc-backend.el 2004-10-18 02:38:24.000000000 +0200 +++ erc.new/erc-backend.el 2004-11-23 03:21:10.000000000 +0100 @@ -243,6 +243,15 @@ (mapconcat 'identity (erc-response.command-args parsed) " ")))) (erc-display-message parsed 'notice proc line))) +(defun erc-parse-nick-prefixes (prefix-string) + (when (string-match "^(\\(.*\\))\\(.*\\)$" prefix-string) + (let ((modes (match-string 1 prefix-string)) + (prefixes (match-string 2 prefix-string))) + (when (= (length modes) (length prefixes)) + (dotimes (i (length modes)) + (add-to-list 'erc-server-nick-prefixes + (cons (aref prefixes i) + (aref modes i)))))))) (def-edebug-spec define-erc-response-handler (&define :name erc-response-handler @@ -432,7 +441,7 @@ (erc-format-message 'JOIN ?n nick ?u login ?h host ?c chnl)))))) (when buffer (set-buffer buffer)) - (erc-update-channel-member chnl nick nick t nil nil host login) + (erc-update-channel-member chnl nick nick t nil host login) ;; on join, we want to stay in the new channel buffer ;;(set-buffer ob) (unless (member "JOIN" erc-hide-list) @@ -612,7 +621,7 @@ ;; message. We will accumulate private identities indefinitely ;; at this point. (erc-update-channel-member (if privp nick tgt) nick nick - privp nil nil host login nil nil t) + privp nil host login nil nil t) (let ((cdata (erc-get-channel-user nick))) (setq fnick (funcall erc-format-nick-function (car cdata) (cdr cdata)))))) (cond @@ -670,7 +679,7 @@ (time (format-time-string "%T %m/%d/%y" (current-time)))) (multiple-value-bind (nick login host) (erc-parse-user (erc-response.sender parsed)) - (erc-update-channel-member ch nick nick nil nil nil host login) + (erc-update-channel-member ch nick nick nil nil host login) (erc-update-channel-topic ch (format "%s\C-c (%s, %s)" topic nick time)) (unless (member "TOPIC" erc-hide-list) (erc-display-message @@ -741,11 +750,13 @@ ;; fill erc-server-parameters (when (string-match "^\\([A-Z]+\\)\=\\(.*\\)$\\|^\\([A-Z]+\\)$" section) - (add-to-list 'erc-server-parameters - `(,(or (match-string 1 section) - (match-string 3 section)) - . - ,(match-string 2 section)))))) + (let ((name (or (match-string 1 section) + (match-string 3 section))) + (value (match-string 2 section))) + (when (string-equal name "PREFIX") + (erc-parse-nick-prefixes value)) + (add-to-list 'erc-server-parameters + (cons name value)))))) (erc-display-message parsed 'notice proc line))) (define-erc-response-handler (221) @@ -974,7 +985,7 @@ (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" name) (setq hopcount (match-string 1 name)) (setq name (match-string 2 name))) - (erc-update-channel-member channel nick nick nil nil nil host user name) + (erc-update-channel-member channel nick nick nil nil host user name) (erc-display-message parsed 'notice 'active (format "%-11s %-10s %-4s %s@%s (%s)" channel nick flag user host name))))) diff -ux '*.elc' -x '*~' erc/erc.el erc.new/erc.el --- erc/erc.el 2004-10-18 00:01:24.000000000 +0200 +++ erc.new/erc.el 2004-11-23 11:32:54.000000000 +0100 @@ -238,6 +238,14 @@ WALLCHOPS - supports sending messages to all operators in a channel") (make-variable-buffer-local 'erc-server-parameters) +(defvar erc-server-nick-prefixes '((?@ . ?o) (?+ . ?v)) + "Variable describing the supported user modes + +This is a alist containing the supported nick prefixes and +corresponding modes. It has the format: + ((PREFIX . MODE) ...) +where PREFIX and MODE are both characters") +(make-variable-buffer-local 'erc-server-nick-prefixes) (defcustom erc-disconnected-hook nil "Run this hook with arguments (NICK IP REASON) when disconnected. @@ -351,7 +359,9 @@ (defstruct (erc-channel-user (:type vector) :named) - op voice + ;; op voice + ;; a list containing mode characters like ?o or ?v or even ?q + modes ;; Last message time (in the form of the return value of ;; (current-time) @@ -463,7 +473,7 @@ (hash-table-p erc-channel-users) (let ((cdata (erc-get-channel-user nick))) (and cdata (cdr cdata) - (erc-channel-user-op (cdr cdata)))))) + (member ?o (erc-channel-user-modes (cdr cdata))))))) (defsubst erc-channel-user-voice-p (nick) "Return `t' if NICK has voice in the current channel." @@ -471,7 +481,21 @@ (hash-table-p erc-channel-users) (let ((cdata (erc-get-channel-user nick))) (and cdata (cdr cdata) - (erc-channel-user-voice (cdr cdata)))))) + (member ?v (erc-channel-user-modes (cdr cdata))))))) + +(defsubst erc-channel-user-get-modes (nick) + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-modes (cdr cdata)))))) + +;;; for compatability +(defsubst erc-channel-user-op (user) + (member ?o (erc-channel-user-modes user))) + +(defsubst erc-channel-user-voice (user) + (member ?v (erc-channel-user-modes user))) (defun erc-get-channel-user-list () "Returns a list of users in the current channel. Each element @@ -511,6 +535,36 @@ erc-channel-users) nicks))) +(defun erc-get-nick-prefix-from-mode (mode) + (with-current-buffer (erc-server-buffer) + (let ((p (rassoc mode erc-server-nick-prefixes))) + (if p + (car p) + nil)))) + +(defun erc-get-nick-prefix-string-from-mode (mode) + (let ((p (erc-get-nick-prefix-from-mode mode))) + (if p + (char-to-string p) + ""))) + +(defun erc-get-nick-mode-from-prefix (pref) + (with-current-buffer (erc-server-buffer) + (let ((p (assoc pref erc-server-nick-prefixes))) + (if p + (cdr p) + nil)))) + +(defun erc-get-nick-mode-string-from-prefix (pref) + (let ((m (erc-get-nick-mode-from-prefix pref))) + (if m + (char-to-string m) + ""))) + +(defun erc-get-server-nick-prefix-alist () + (with-current-buffer (erc-server-buffer) + erc-server-nick-prefixes)) + (defun erc-get-server-nickname-alist () "Returns an alist of known nicknames on the current server." (if (erc-process-alive) @@ -4734,13 +4788,12 @@ "Format a nickname such that @ or + are prefix for the NICK if OP or VOICE are t respectively." (if user - (let (op voice) + (let (modes) (if channel-data - (setq op (erc-channel-user-op channel-data) - voice (erc-channel-user-voice channel-data))) - (concat (if voice "+" "") - (if op "@" "") - (erc-server-user-nickname user))))) + (setq modes (erc-channel-user-modes channel-data))) + (concat + (mapconcat 'erc-get-nick-prefix-string-from-mode modes "") + (erc-server-user-nickname user))))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized" @@ -5240,27 +5293,24 @@ Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." - (let (names name op voice) + (let (names name op modes) ;; We need to delete "" because in XEmacs, (split-string "a ") ;; returns ("a" ""). (setq names (delete "" (split-string names-string))) (let ((erc-channel-members-changed-hook nil)) (dolist (item names) - (cond ((string-match "^@\\(.*\\)$" item) - (setq name (match-string 1 item) - op 'on - voice 'off)) - ((string-match "^+\\(.*\\)$" item) - (setq name (match-string 1 item) - op 'off - voice 'on)) - (t (setq name item - op 'off - voice 'off))) + (block search-prefix + (dolist (mp (erc-get-server-nick-prefix-alist)) + (let ((re (format "%c\\(.*\\)$" (car mp)))) + (when (string-match re item) + (setq name (match-string 1 item) + modes (list (cdr mp))) + (return-from search-prefix)))) + (setq name item)) (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member - name name t op voice))) + name name t modes))) (run-hooks 'erc-channel-members-changed-hook))) (defcustom erc-channel-members-changed-hook nil @@ -5320,16 +5370,14 @@ changed)) (defun erc-update-current-channel-member - (nick new-nick &optional add op voice host login full-name info + (nick new-nick &optional add modes host login full-name info update-message-time) "Updates the stored user information for the user with nickname NICK. `erc-update-user' is called to handle changes to nickname, -host, login, full-name, and info. If `op' or `voice' are -non-nil, they must be equal to either `on' or `off', in which -case the operator or voice status of USER in the current channel -is changed accordingly. If `update-message-time' is non-nil, the -last-message-time of the user in the current channel is set -to (current-time). +host, login, full-name, and info. MODES contains a list of +characters describing valid user modes. If `update-message-time' +is non-nil, the last-message-time of the user in the current +channel is set to (current-time). If ADD is non-nil, the user will be added with the specified information if it is not already present in the user or channel @@ -5347,20 +5395,13 @@ (if cuser (progn (erc-log (format "update-member: user = %S, cuser = %S" user cuser)) - (when (and op - (not (eq (erc-channel-user-op cuser) op))) + (when modes + (when (equal modes '(nil)) + (setq modes nil)) + (unless (equal (erc-channel-user-modes cuser) modes) (setq changed t) - (setf (erc-channel-user-op cuser) - (cond ((eq op 'on) t) - ((eq op 'off) nil) - (t op)))) - (when (and voice - (not (eq (erc-channel-user-voice cuser) voice))) - (setq changed t) - (setf (erc-channel-user-voice cuser) - (cond ((eq voice 'on) t) - ((eq voice 'off) nil) - (t voice)))) + (setf (erc-channel-user-modes cuser) modes))) + (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed @@ -5381,12 +5422,7 @@ (cons (current-buffer) (erc-server-user-buffers user)))) (setq cuser (make-erc-channel-user - :op (cond ((eq op 'on) t) - ((eq op 'off) nil) - (t op)) - :voice (cond ((eq voice 'on) t) - ((eq voice 'off) nil) - (t voice)) + :modes modes :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) @@ -5397,7 +5433,7 @@ (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick - &optional add op voice host login + &optional add modes host login full-name info update-message-time) "Updates user and channel information for the user with nickname NICK in channel CHANNEL. @@ -5405,7 +5441,7 @@ See also: `erc-update-current-channel-member'" (erc-with-buffer (channel) - (erc-update-current-channel-member nick new-nick add op voice host + (erc-update-current-channel-member nick new-nick add modes host login full-name info update-message-time))) @@ -5560,16 +5596,24 @@ (let ((mode (nth 0 (car arg-modes))) (onoff (nth 1 (car arg-modes))) (arg (nth 2 (car arg-modes)))) - (cond ((string-match "^[oO]" mode) - (erc-update-channel-member tgt arg arg nil onoff)) - ((string-match "^[Vv]" mode) - (erc-update-channel-member tgt arg arg nil nil - onoff)) - ((string-match "^[Ll]" mode) - (erc-update-channel-limit tgt onoff arg)) - ((string-match "^[Kk]" mode) - (erc-update-channel-key tgt onoff arg)) - (t nil)); only ops are tracked now + (block search-mode + (dolist (pm (erc-get-server-nick-prefix-alist)) + (let ((re (format "^%c" (cdr pm))) + (modes (copy-list + (erc-channel-user-get-modes arg)))) + (when (string-match re mode) + (if (eq onoff 'on) + (add-to-list 'modes (cdr pm)) + (setq modes (delete (cdr pm) modes))) + (erc-update-channel-member tgt arg arg nil + (or modes '(nil))) + (return-from search-mode)))) + (cond + ((string-match "^[Ll]" mode) + (erc-update-channel-limit tgt onoff arg)) + ((string-match "^[Kk]" mode) + (erc-update-channel-key tgt onoff arg)) + (t nil))); only ops are tracked now (setq arg-modes (cdr arg-modes)))) (erc-update-mode-line buf)))) ;; nick modes - ignored at this point @@ -6546,7 +6590,7 @@ (user (if channel-data (car channel-data) (erc-get-server-user word))) - host login full-name info nick op voice) + host login full-name info nick modes) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) @@ -6554,18 +6598,16 @@ full-name (erc-server-user-full-name user) info (erc-server-user-info user)) (if cuser - (setq op (erc-channel-user-op cuser) - voice (erc-channel-user-voice cuser))) + (setq modes (erc-channel-user-modes cuser))) (if (interactive-p) (message "%s is %s@%s%s%s" nick login host (if full-name (format " (%s)" full-name) "") - (if (or op voice) - (format " and is +%s%s on %s" - (if op "o" "") - (if voice "v" "") - (erc-default-target)) - "")) + (if modes + (format " and is +%s on %s" + (mapconcat 'erc-get-nick-prefix-string-from-mode modes) + (erc-default-target)) + "")) user)))) ;; (defun erc-operator-p (nick &optional channel) |