* bug#17755: 24.3; ERC user mode support @ 2014-06-11 10:34 kelvin.white77 2014-06-11 11:45 ` Kelvin White 2014-10-02 19:31 ` Paul Eggert 0 siblings, 2 replies; 8+ messages in thread From: kelvin.white77 @ 2014-06-11 10:34 UTC (permalink / raw) To: 17755 ERC lacks support for user modes other than +o/+v (OP/VOICE), making it difficult for IRC users to know what modes any user may have. Currently user nicknames do not include any mode prefix by default. By setting `erc-format-nick-function' to erc-format-@nick, a user can enable prefixes @, or +, added to user nicknames. While that may be a sane default, most IRC servers support more user modes. ERC already parses the prefixes sent in the server parameters, and adds available modes to a list, but they are never utilized. In GNU Emacs 24.3.1 (x86_64-pc-linux-gnu) of 2013-07-26 on roseapple, modified by Debian System Description: Ubuntu 13.10 Configured using: `configure '--build' 'x86_64-linux-gnu' '--build' 'x86_64-linux-gnu' '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' '--localstatedir=/var/lib' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--with-pop=yes' '--enable-locallisppath=/etc/emacs24:/etc/emacs:/usr/local/share/emacs/24.3/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/24.3/site-lisp:/usr/share/emacs/site-lisp' '--with-crt-dir=/usr/lib/x86_64-linux-gnu' '--with-x=no' '--without-gconf' 'build_alias=x86_64-linux-gnu' 'CFLAGS=-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wall' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro' 'CPPFLAGS=-D_FORTIFY_SOURCE=2'' Important settings: value of $LC_CTYPE: en_US.UTF-8 value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix default enable-multibyte-characters: t Major mode: Lisp Interaction Minor modes in effect: paredit-mode: t erc-services-mode: t ido-everywhere: t recentf-mode: t show-paren-mode: t erc-list-mode: t erc-menu-mode: t erc-autojoin-mode: t erc-ring-mode: t erc-networks-mode: t erc-pcomplete-mode: t erc-track-mode: t erc-track-minor-mode: t erc-match-mode: t erc-button-mode: t erc-fill-mode: t erc-stamp-mode: t erc-netsplit-mode: t erc-irccontrols-mode: t erc-noncommands-mode: t erc-move-to-prompt-mode: t erc-readonly-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t line-number-mode: t transient-mark-mode: t Recent input: A C-x C-s C-x ESC O C C-x ESC O D C-x ESC O C C-x ESC O D C-x ESC O C h a h a RET n i c e RET C-x ESC O D C-x ESC O C C-x ESC O D ESC O B ESC O B C-x C-s C-x f e r c . e l RET ESC O A ESC O A C-a C-k C-y \ RET DEL RET RET C-y ESC O A ESC O A ESC O D ESC O D ESC O D ESC O D ESC O D ESC O D ESC O D m y - C-x C-s ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A TAB ESC O B TAB ESC O B TAB ESC O B TAB ESC O B TAB ESC O B TAB ESC O A TAB ESC O A TAB ESC O A TAB ESC O A C-a TAB ESC O D C-@ C-a DEL ESC O B TAB ESC O D C-@ C-a DEL ESC O B TAB ESC O D C-@ C-a DEL ESC O B TAB ESC O D C-@ C-a DEL C-x C-s C-x C-c ESC [ > 0 ; 9 5 ; c C-x C-c ESC [ > 0 ; 9 5 ; c C-x C-c ESC [ > 0 ; 9 5 ; c ESC x r e p o r t - e m a c s - b u g RET Recent messages: Wrote /home/l3thal/projects/emacs-dev/lisp/erc/erc.el Mark set [4 times] Saving file /home/l3thal/projects/emacs-dev/lisp/erc/erc.el... Wrote /home/l3thal/projects/emacs-dev/lisp/erc/erc.el (No files need saving) When done with this frame, type C-x 5 0 (No files need saving) When done with this frame, type C-x 5 0 (No files need saving) When done with this frame, type C-x 5 0 Load-path shadows: /usr/share/emacs/24.3/site-lisp/debian-startup hides /usr/share/emacs/site-lisp/debian-startup /usr/share/emacs24/site-lisp/dictionaries-common/flyspell hides /usr/share/emacs/24.3/lisp/textmodes/flyspell /usr/share/emacs24/site-lisp/dictionaries-common/ispell hides /usr/share/emacs/24.3/lisp/textmodes/ispell Features: (shadow sort mail-extr emacsbug message rfc822 mml mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums mail-utils tabify misearch multi-isearch vc-git gnutls network-stream starttls tls server magit-autoloads info git-rebase-mode-autoloads git-commit-mode-autoloads finder-inf package awesome untabify-file paredit erc-init erc-services erc-names ido recentf tree-widget paren erc-menu erc-join erc-ring erc-networks erc-pcomplete pcomplete erc-track erc-match erc-button wid-edit erc-fill erc-stamp erc-netsplit erc-goodies erc erc-backend erc-compat format-spec auth-source eieio gnus-util time-date mm-util mail-prsvr password-cache cus-start cus-load warnings slime-fancy slime-trace-dialog slime-fontifying-fu slime-package-fu slime-references slime-compiler-notes-tree slime-scratch slime-presentations bridge slime-fuzzy slime-fancy-trace slime-fancy-inspector slime-c-p-c slime-editing-commands slime-autodoc advice advice-preload eldoc slime-repl slime-parse slime byte-opt bytecomp byte-compile cconv derived help-fns edmacro kmacro gud compile tool-bar apropos etags arc-mode archive-mode noutline outline easy-mmode easymenu pp comint regexp-opt ansi-color ring hyperspec cl-macs gv thingatpt browse-url cl cl-lib slime-autoloads ediff-hook vc-hooks lisp-float-type tabulated-list newcomment lisp-mode register page menu-bar rfn-eshadow timer select mouse jit-lock font-lock syntax facemenu font-core frame cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev minibuffer loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote make-network-process dbusbind multi-tty emacs) ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-11 10:34 bug#17755: 24.3; ERC user mode support kelvin.white77 @ 2014-06-11 11:45 ` Kelvin White 2014-06-17 16:03 ` Stefan Monnier 2014-10-02 19:31 ` Paul Eggert 1 sibling, 1 reply; 8+ messages in thread From: Kelvin White @ 2014-06-11 11:45 UTC (permalink / raw) To: 17755 [-- Attachment #1.1: Type: text/plain, Size: 6183 bytes --] Here is the patch to add this feature On Wed, Jun 11, 2014 at 6:34 AM, <kelvin.white77@gmail.com> wrote: > ERC lacks support for user modes other than +o/+v (OP/VOICE), making it > difficult for IRC users to know what modes any user may have. Currently > user nicknames do not include any mode prefix by default. By setting > `erc-format-nick-function' to erc-format-@nick, a user can enable prefixes > @, or +, added to user nicknames. While that may be a sane default, most > IRC > servers support more user modes. ERC already parses the prefixes sent in > the server parameters, and adds available modes to a list, but they are > never utilized. > > > In GNU Emacs 24.3.1 (x86_64-pc-linux-gnu) > of 2013-07-26 on roseapple, modified by Debian > System Description: Ubuntu 13.10 > > Configured using: > `configure '--build' 'x86_64-linux-gnu' '--build' 'x86_64-linux-gnu' > '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' > '--localstatedir=/var/lib' '--infodir=/usr/share/info' > '--mandir=/usr/share/man' '--with-pop=yes' > > '--enable-locallisppath=/etc/emacs24:/etc/emacs:/usr/local/share/emacs/24.3/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/24.3/site-lisp:/usr/share/emacs/site-lisp' > '--with-crt-dir=/usr/lib/x86_64-linux-gnu' '--with-x=no' > '--without-gconf' 'build_alias=x86_64-linux-gnu' 'CFLAGS=-g -O2 > -fstack-protector --param=ssp-buffer-size=4 -Wformat > -Werror=format-security -Wall' 'LDFLAGS=-Wl,-Bsymbolic-functions > -Wl,-z,relro' 'CPPFLAGS=-D_FORTIFY_SOURCE=2'' > > Important settings: > value of $LC_CTYPE: en_US.UTF-8 > value of $LANG: en_US.UTF-8 > locale-coding-system: utf-8-unix > default enable-multibyte-characters: t > > Major mode: Lisp Interaction > > Minor modes in effect: > paredit-mode: t > erc-services-mode: t > ido-everywhere: t > recentf-mode: t > show-paren-mode: t > erc-list-mode: t > erc-menu-mode: t > erc-autojoin-mode: t > erc-ring-mode: t > erc-networks-mode: t > erc-pcomplete-mode: t > erc-track-mode: t > erc-track-minor-mode: t > erc-match-mode: t > erc-button-mode: t > erc-fill-mode: t > erc-stamp-mode: t > erc-netsplit-mode: t > erc-irccontrols-mode: t > erc-noncommands-mode: t > erc-move-to-prompt-mode: t > erc-readonly-mode: t > file-name-shadow-mode: t > global-font-lock-mode: t > font-lock-mode: t > auto-composition-mode: t > auto-encryption-mode: t > auto-compression-mode: t > line-number-mode: t > transient-mark-mode: t > > Recent input: > A C-x C-s C-x ESC O C C-x ESC O D C-x ESC O C C-x ESC > O D C-x ESC O C h a h a RET n i c e RET C-x ESC O D > C-x ESC O C C-x ESC O D ESC O B ESC O B C-x C-s C-x > f e r c . e l RET ESC O A ESC O A C-a C-k C-y \ RET > DEL RET RET C-y ESC O A ESC O A ESC O D ESC O D ESC > O D ESC O D ESC O D ESC O D ESC O D m y - C-x C-s ESC > O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A > ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC > O A ESC O A ESC O A ESC O A ESC O A ESC O A ESC O A > ESC O A TAB ESC O B TAB ESC O B TAB ESC O B TAB ESC > O B TAB ESC O B TAB ESC O A TAB ESC O A TAB ESC O A > TAB ESC O A C-a TAB ESC O D C-@ C-a DEL ESC O B TAB > ESC O D C-@ C-a DEL ESC O B TAB ESC O D C-@ C-a DEL > ESC O B TAB ESC O D C-@ C-a DEL C-x C-s C-x C-c ESC > [ > 0 ; 9 5 ; c C-x C-c ESC [ > 0 ; 9 5 ; c C-x C-c > ESC [ > 0 ; 9 5 ; c ESC x r e p o r t - e m a c s - > b u g RET > > Recent messages: > Wrote /home/l3thal/projects/emacs-dev/lisp/erc/erc.el > Mark set [4 times] > Saving file /home/l3thal/projects/emacs-dev/lisp/erc/erc.el... > Wrote /home/l3thal/projects/emacs-dev/lisp/erc/erc.el > (No files need saving) > When done with this frame, type C-x 5 0 > (No files need saving) > When done with this frame, type C-x 5 0 > (No files need saving) > When done with this frame, type C-x 5 0 > > Load-path shadows: > /usr/share/emacs/24.3/site-lisp/debian-startup hides > /usr/share/emacs/site-lisp/debian-startup > /usr/share/emacs24/site-lisp/dictionaries-common/flyspell hides > /usr/share/emacs/24.3/lisp/textmodes/flyspell > /usr/share/emacs24/site-lisp/dictionaries-common/ispell hides > /usr/share/emacs/24.3/lisp/textmodes/ispell > > Features: > (shadow sort mail-extr emacsbug message rfc822 mml mml-sec mm-decode > mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader > sendmail rfc2047 rfc2045 ietf-drums mail-utils tabify misearch > multi-isearch vc-git gnutls network-stream starttls tls server > magit-autoloads info git-rebase-mode-autoloads git-commit-mode-autoloads > finder-inf package awesome untabify-file paredit erc-init erc-services > erc-names ido recentf tree-widget paren erc-menu erc-join erc-ring > erc-networks erc-pcomplete pcomplete erc-track erc-match erc-button > wid-edit erc-fill erc-stamp erc-netsplit erc-goodies erc erc-backend > erc-compat format-spec auth-source eieio gnus-util time-date mm-util > mail-prsvr password-cache cus-start cus-load warnings slime-fancy > slime-trace-dialog slime-fontifying-fu slime-package-fu slime-references > slime-compiler-notes-tree slime-scratch slime-presentations bridge > slime-fuzzy slime-fancy-trace slime-fancy-inspector slime-c-p-c > slime-editing-commands slime-autodoc advice advice-preload eldoc > slime-repl slime-parse slime byte-opt bytecomp byte-compile cconv > derived help-fns edmacro kmacro gud compile tool-bar apropos etags > arc-mode archive-mode noutline outline easy-mmode easymenu pp comint > regexp-opt ansi-color ring hyperspec cl-macs gv thingatpt browse-url cl > cl-lib slime-autoloads ediff-hook vc-hooks lisp-float-type > tabulated-list newcomment lisp-mode register page menu-bar rfn-eshadow > timer select mouse jit-lock font-lock syntax facemenu font-core frame > cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao > korean japanese hebrew greek romanian slovak czech european ethiopic > indian cyrillic chinese case-table epa-hook jka-cmpr-hook help simple > abbrev minibuffer loaddefs button faces cus-face macroexp files > text-properties overlay sha1 md5 base64 format env code-pages mule > custom widget hashtable-print-readable backquote make-network-process > dbusbind multi-tty emacs) > [-- Attachment #1.2: Type: text/html, Size: 7098 bytes --] [-- Attachment #2: erc.diff --] [-- Type: text/plain, Size: 28182 bytes --] diff --ignore-space-change -c '-F^[_a-zA-Z0-9$]+ *(' projects/emacs/lisp/erc/ChangeLog projects/emacs-dev/lisp/erc/ChangeLog *** projects/emacs/lisp/erc/ChangeLog 2014-06-10 09:04:50.536885271 -0400 --- projects/emacs-dev/lisp/erc/ChangeLog 2014-06-11 07:30:02.422563635 -0400 *************** *** 1,3 **** --- 1,15 ---- + 2014-06-11 Kelvin White <kelvin.white77@gmail.com> + + * erc-backend.el Handle user modes in relevent server responses + * erc.el Better user mode support. + (erc-channel-user): Add members for new modes. + (erc-channel-member-halfop-p, erc-channel-user-admin-p, erc-channel-user-owner-p): Use new struct members. + (erc-format-nick, erc-format-@nick): Display user modes as nick prefix. + (erc-nick-prefix-face, erc-my-nick-prefix-face): Add new faces to separate colors if desired. + (erc-get-user-mode-prefix): Return symbol for mode prefix. + (erc-update-channel-member, erc-update-current-channel-member, erc-channel-receive-names): Update channel users. + (erc-nick-at-point): Return correct user info. + 2014-04-04 Stefan Monnier <monnier@iro.umontreal.ca> * erc.el (erc-invite-only-mode, erc-toggle-channel-mode): Simplify. *************** *** 615,618 **** ;; coding: utf-8 ;; add-log-time-zone-rule: t ;; End: - --- 627,629 ---- diff --ignore-space-change -c '-F^[_a-zA-Z0-9$]+ *(' projects/emacs/lisp/erc/erc-backend.el projects/emacs-dev/lisp/erc/erc-backend.el *** projects/emacs/lisp/erc/erc-backend.el 2014-06-11 06:53:48.176451824 -0400 --- projects/emacs-dev/lisp/erc/erc-backend.el 2014-06-11 06:55:57.682449183 -0400 *************** *** 1244,1250 **** (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) ;; on join, we want to stay in the new channel buffer ;;(set-buffer ob) (erc-display-message parsed nil buffer str)))))) --- 1244,1250 ---- (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 nil nil nil host login) ;; on join, we want to stay in the new channel buffer ;;(set-buffer ob) (erc-display-message parsed nil buffer str)))))) *************** *** 1413,1419 **** ;; 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) (let ((cdata (erc-get-channel-user nick))) (setq fnick (funcall erc-format-nick-function (car cdata) (cdr cdata)))))) --- 1413,1419 ---- ;; message. We will accumulate private identities indefinitely ;; at this point. (erc-update-channel-member (if privp nick tgt) nick nick ! privp nil nil nil nil nil host login nil nil t) (let ((cdata (erc-get-channel-user nick))) (setq fnick (funcall erc-format-nick-function (car cdata) (cdr cdata)))))) *************** *** 1470,1476 **** (current-time)))) (pcase-let ((`(,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-topic ch (format "%s\C-o (%s, %s)" topic nick time)) (erc-display-message parsed 'notice (erc-get-buffer ch proc) 'TOPIC ?n nick ?u login ?h host --- 1470,1476 ---- (current-time)))) (pcase-let ((`(,nick ,login ,host) (erc-parse-user (erc-response.sender parsed)))) ! (erc-update-channel-member ch nick nick nil nil nil nil nil nil host login) (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time)) (erc-display-message parsed 'notice (erc-get-buffer ch proc) 'TOPIC ?n nick ?u login ?h host *************** *** 1800,1807 **** (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name) (setq hopcount (match-string 1 full-name)) (setq full-name (match-string 2 full-name))) ! (erc-update-channel-member channel nick nick nil nil nil host ! user full-name) (erc-display-message parsed 'notice 'active 's352 ?c channel ?n nick ?a away-flag ?u user ?h host ?f full-name)))) --- 1800,1806 ---- (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name) (setq hopcount (match-string 1 full-name)) (setq full-name (match-string 2 full-name))) ! (erc-update-channel-member channel nick nick nil nil nil nil nil nil host user full-name) (erc-display-message parsed 'notice 'active 's352 ?c channel ?n nick ?a away-flag ?u user ?h host ?f full-name)))) diff --ignore-space-change -c '-F^[_a-zA-Z0-9$]+ *(' projects/emacs/lisp/erc/erc.el projects/emacs-dev/lisp/erc/erc.el *** projects/emacs/lisp/erc/erc.el 2014-06-11 06:53:48.176451824 -0400 --- projects/emacs-dev/lisp/erc/erc.el 2014-06-11 07:09:49.603393410 -0400 *************** *** 370,376 **** ) (cl-defstruct (erc-channel-user (:type vector) :named) ! op voice ;; Last message time (in the form of the return value of ;; (current-time) ;; --- 370,376 ---- ) (cl-defstruct (erc-channel-user (:type vector) :named) ! voice halfop op admin owner ;; Last message time (in the form of the return value of ;; (current-time) ;; *************** *** 475,480 **** --- 475,496 ---- erc-channel-users) (clrhash erc-channel-users))) + (defsubst erc-channel-user-owner-p (nick) + "Return t if NICK is an owner of the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-owner (cdr cdata)))))) + + (defsubst erc-channel-user-admin-p (nick) + "Return t if NICK is an admin in the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-admin (cdr cdata)))))) + (defsubst erc-channel-user-op-p (nick) "Return t if NICK is an operator in the current channel." (and nick *************** *** 483,488 **** --- 499,512 ---- (and cdata (cdr cdata) (erc-channel-user-op (cdr cdata)))))) + (defsubst erc-channel-user-halfop-p (nick) + "Return t if NICK is a half-operator in the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-halfop (cdr cdata)))))) + (defsubst erc-channel-user-voice-p (nick) "Return t if NICK has voice in the current channel." (and nick *************** *** 1122,1127 **** --- 1146,1159 ---- "ERC default face." :group 'erc-faces) + (defface erc-nick-prefix-face '((t :weight bold)) + "ERC face used for user mode prefix." + :group 'erc-faces) + + (defface erc-my-nick-prefix-face '((t :weight bold)) + "ERC face used for my user mode prefix." + :group 'erc-faces) + (defface erc-direct-msg-face '((t :foreground "IndianRed")) "ERC face used for messages you receive in the main erc buffer." :group 'erc-faces) *************** *** 4192,4215 **** See also `erc-format-nick-function'." (when user (erc-server-user-nickname user))) (defun erc-format-@nick (&optional user channel-data) "Format the nickname of USER showing if USER is an operator or has voice. Operators have \"@\" and users with voice have \"+\" as a prefix. Use CHANNEL-DATA to determine op and voice status. See also `erc-format-nick-function'." (when user ! (let ((op (and channel-data (erc-channel-user-op channel-data) "@")) ! (voice (and channel-data (erc-channel-user-voice channel-data) "+"))) ! (concat voice op (erc-server-user-nickname user))))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized." (if erc-show-my-nick ! (let ((open "<") (close "> ") ! (nick (erc-current-nick))) (concat (erc-propertize open 'face 'erc-default-face) (erc-propertize nick 'face 'erc-my-nick-face) (erc-propertize close 'face 'erc-default-face))) (let ((prefix "> ")) --- 4224,4257 ---- See also `erc-format-nick-function'." (when user (erc-server-user-nickname user))) + (defun erc-get-user-mode-prefix (user) + (when user + (cond ((erc-channel-user-voice-p user) "+") + ((erc-channel-user-half-op-p user) "%") + ((erc-channel-user-op-p user) "@") + ((erc-channel-user-admin-p user) "&") + ((erc-channel-user-owner-p user) "~") + (t "")))) + (defun erc-format-@nick (&optional user channel-data) "Format the nickname of USER showing if USER is an operator or has voice. Operators have \"@\" and users with voice have \"+\" as a prefix. Use CHANNEL-DATA to determine op and voice status. See also `erc-format-nick-function'." (when user ! (let ((nick (erc-server-user-nickname user))) ! (concat (erc-propertize (erc-get-user-mode-prefix nick) 'face 'erc-nick-prefix-face) nick)))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized." (if erc-show-my-nick ! (let* ((open "<") (close "> ") ! (nick (erc-current-nick)) ! (mode (erc-get-user-mode-prefix nick))) (concat (erc-propertize open 'face 'erc-default-face) + (erc-propertize mode 'face 'erc-my-nick-prefix-face) (erc-propertize nick 'face 'erc-my-nick-face) (erc-propertize close 'face 'erc-default-face))) (let ((prefix "> ")) *************** *** 4685,4691 **** (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer erc-server-parameters))) ;; provide a sane default ! "(ov)@+")) types chars) (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) (setq types (match-string 1 str) --- 4727,4733 ---- (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer erc-server-parameters))) ;; provide a sane default ! "(qaohv)~&@%+")) types chars) (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) (setq types (match-string 1 str) *************** *** 4705,4714 **** Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." ! (let (prefix op-ch voice-ch names name op voice) (setq prefix (erc-parse-prefix)) ! (setq op-ch (cdr (assq ?o prefix)) ! voice-ch (cdr (assq ?v prefix))) ;; We need to delete "" because in XEmacs, (split-string "a ") ;; returns ("a" ""). (setq names (delete "" (split-string names-string))) --- 4747,4759 ---- Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." ! (let (prefix voice-ch hop-ch op-ch adm-ch own-ch names name voice halfop op admin owner) (setq prefix (erc-parse-prefix)) ! (setq voice-ch (cdr (assq ?v prefix)) ! hop-ch (cdr (assq ?h prefix)) ! op-ch (cdr (assq ?o prefix)) ! adm-ch (cdr (assq ?a prefix)) ! own-ch (cdr (assq ?q prefix))) ;; We need to delete "" because in XEmacs, (split-string "a ") ;; returns ("a" ""). (setq names (delete "" (split-string names-string))) *************** *** 4718,4742 **** (if (rassq (elt item 0) prefix) (cond ((= (length item) 1) (setq updatep nil)) ((eq (elt item 0) op-ch) (setq name (substring item 1) op 'on ! voice 'off)) ! ((eq (elt item 0) voice-ch) (setq name (substring item 1) op 'off ! voice 'on)) (t (setq name (substring item 1) op 'off ! voice 'off))) (setq name item op 'off ! voice 'off)) (when updatep (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member ! name name t op voice))))) (run-hooks 'erc-channel-members-changed-hook))) (defcustom erc-channel-members-changed-hook nil --- 4763,4820 ---- (if (rassq (elt item 0) prefix) (cond ((= (length item) 1) (setq updatep nil)) + ((eq (elt item 0) voice-ch) + (setq name (substring item 1) + op 'off + voice 'on + halfop 'off + admin 'off + owner 'off)) + ((eq (elt item 0) hop-ch) + (setq name (substring item 1) + op 'off + voice 'off + halfop 'on + admin 'off + owner 'off)) ((eq (elt item 0) op-ch) (setq name (substring item 1) op 'on ! voice 'off ! halfop 'off ! admin 'off ! owner 'off)) ! ((eq (elt item 0) adm-ch) ! (setq name (substring item 1) ! op 'off ! voice 'off ! halfop 'off ! admin 'on ! owner 'off)) ! ((eq (elt item 0) own-ch) (setq name (substring item 1) op 'off ! voice 'off ! halfop 'off ! admin 'off ! owner 'on)) (t (setq name (substring item 1) op 'off ! voice 'off ! halfop 'off ! admin 'off ! owner 'off))) (setq name item op 'off ! voice 'off ! halfop 'off ! admin 'off ! owner 'off)) (when updatep (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member ! name name t voice halfop op admin owner))))) (run-hooks 'erc-channel-members-changed-hook))) (defcustom erc-channel-members-changed-hook nil *************** *** 4795,4810 **** changed)) (defun erc-update-current-channel-member ! (nick new-nick &optional add op voice host login full-name info update-message-time) "Update 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 the 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). 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 --- 4873,4887 ---- changed)) (defun erc-update-current-channel-member ! (nick new-nick &optional add voice halfop op admin owner host login full-name info update-message-time) "Update 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 VOICE HALFOP OP ADMIN or OWNER ! are non-nil, they must be equal to either `on' or `off', in which ! case the status of the 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). 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 *************** *** 4822,4827 **** --- 4899,4918 ---- (if cuser (progn (erc-log (format "update-member: user = %S, cuser = %S" user cuser)) + (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)))) + (when (and halfop + (not (eq (erc-channel-user-halfop cuser) halfop))) + (setq changed t) + (setf (erc-channel-user-halfop cuser) + (cond ((eq halfop 'on) t) + ((eq halfop 'off) nil) + (t halfop)))) (when (and op (not (eq (erc-channel-user-op cuser) op))) (setq changed t) *************** *** 4829,4841 **** (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)))) (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed --- 4920,4939 ---- (cond ((eq op 'on) t) ((eq op 'off) nil) (t op)))) ! (when (and admin ! (not (eq (erc-channel-user-admin cuser) admin))) (setq changed t) ! (setf (erc-channel-user-admin cuser) ! (cond ((eq admin 'on) t) ! ((eq admin 'off) nil) ! (t admin)))) ! (when (and owner ! (not (eq (erc-channel-user-owner cuser) owner))) ! (setq changed t) ! (setf (erc-channel-user-owner cuser) ! (cond ((eq owner 'on) t) ! ((eq owner 'off) nil) ! (t owner)))) (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed *************** *** 4856,4867 **** (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)) :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) --- 4954,4974 ---- (cons (current-buffer) (erc-server-user-buffers user)))) (setq cuser (make-erc-channel-user :voice (cond ((eq voice 'on) t) ((eq voice 'off) nil) (t voice)) + :halfop (cond ((eq halfop 'on) t) + ((eq halfop 'off) nil) + (t halfop)) + :op (cond ((eq op 'on) t) + ((eq op 'off) nil) + (t op)) + :admin (cond ((eq admin 'on) t) + ((eq admin 'off) nil) + (t admin)) + :owner (cond ((eq owner 'on) t) + ((eq owner 'off) nil) + (t owner)) :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) *************** *** 4872,4878 **** (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick ! &optional add op voice host login full-name info update-message-time) "Update user and channel information for the user with nickname NICK in channel CHANNEL. --- 4979,4985 ---- (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick ! &optional add voice halfop op admin owner host login full-name info update-message-time) "Update user and channel information for the user with nickname NICK in channel CHANNEL. *************** *** 4880,4886 **** See also: `erc-update-current-channel-member'." (erc-with-buffer (channel) ! (erc-update-current-channel-member nick new-nick add op voice host login full-name info update-message-time))) --- 4987,4993 ---- See also: `erc-update-current-channel-member'." (erc-with-buffer (channel) ! (erc-update-current-channel-member nick new-nick add voice halfop op admin owner host login full-name info update-message-time))) *************** *** 4979,4985 **** (while chars (cond ((string= (car chars) "+") (setq add-p t)) ((string= (car chars) "-") (setq add-p nil)) ! ((string-match "^[ovbOVB]" (car chars)) (setq arg-modes (cons (list (car chars) (if add-p 'on 'off) (if args (car args) nil)) --- 5086,5092 ---- (while chars (cond ((string= (car chars) "+") (setq add-p t)) ((string= (car chars) "-") (setq add-p nil)) ! ((string-match "^[qaovhbQAOVHB]" (car chars)) (setq arg-modes (cons (list (car chars) (if add-p 'on 'off) (if args (car args) nil)) *************** *** 5035,5045 **** (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) --- 5142,5157 ---- (let ((mode (nth 0 (car arg-modes))) (onoff (nth 1 (car arg-modes))) (arg (nth 2 (car arg-modes)))) ! (cond ((string-match "^[Vv]" mode) (erc-update-channel-member tgt arg arg nil onoff)) ! ((string-match "^[hH]" mode) ! (erc-update-channel-member tgt arg arg nil nil onoff)) ! ((string-match "^[oO]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil onoff)) ! ((string-match "^[aA]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil nil onoff)) ! ((string-match "^[qQ]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil nil nil onoff)) ((string-match "^[Ll]" mode) (erc-update-channel-limit tgt onoff arg)) ((string-match "^[Kk]" mode) *************** *** 5978,6003 **** (user (if channel-data (car channel-data) (erc-get-server-user word))) ! host login full-name nick op voice) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) login (erc-server-user-login user) full-name (erc-server-user-full-name user)) (if cuser ! (setq op (erc-channel-user-op cuser) ! voice (erc-channel-user-voice cuser))) (if (called-interactively-p 'interactive) (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)) "")) ! user)))) (defun erc-away-time () "Return non-nil if the current ERC process is set away. --- 6090,6121 ---- (user (if channel-data (car channel-data) (erc-get-server-user word))) ! host login full-name nick voice halfop op admin owner) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) login (erc-server-user-login user) full-name (erc-server-user-full-name user)) (if cuser ! (setq voice (erc-channel-user-voice cuser) ! halfop (erc-channel-user-halfop cuser) ! op (erc-channel-user-op cuser) ! admin (erc-channel-user-admin cuser) ! owner (erc-channel-user-owner cuser)))) (if (called-interactively-p 'interactive) (message "%s is %s@%s%s%s" nick login host (if full-name (format " (%s)" full-name) "") ! (if (or voice halfop op admin owner) (format " and is +%s%s on %s" (if voice "v" "") + (if halfop "h" "") + (if op "o" "") + (if admin "a" "") + (if owner "q" "") (erc-default-target)) "")) ! user))) (defun erc-away-time () "Return non-nil if the current ERC process is set away. ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-11 11:45 ` Kelvin White @ 2014-06-17 16:03 ` Stefan Monnier 2014-06-18 14:40 ` Kelvin White 0 siblings, 1 reply; 8+ messages in thread From: Stefan Monnier @ 2014-06-17 16:03 UTC (permalink / raw) To: Kelvin White Cc: Lawrence Mitchell, Michael Olson, 17755, mlang, Diane Murray, Alex Schroeder, Julien Danjou, Francis Litterio, Jorgen Schaefer > Here is the patch to add this feature Thanks, here are some comments on it. I wish someone who has worked on ERC could say something. I never use(d) IRC and have hence no clue what is a "user mode prefix", for example. > *************** > *** 1244,1250 **** > (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) > ;; on join, we want to stay in the new channel buffer > ;;(set-buffer ob) > (erc-display-message parsed nil buffer str)))))) > --- 1244,1250 ---- > (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 nil nil nil host login) > ;; on join, we want to stay in the new channel buffer > ;;(set-buffer ob) > (erc-display-message parsed nil buffer str)))))) In my opinion, erc-update-channel-member had too many arguments already. Maybe some of these args should be combined into an erc-channel-user object? > + (defsubst erc-channel-user-owner-p (nick) > + "Return t if NICK is an owner of the current channel." Usually we say "non-nil" rather than "t", unless the callers need to rely on the return value being t rather than some other non-nil value. > + (defface erc-nick-prefix-face '((t :weight bold)) > + "ERC face used for user mode prefix." > + :group 'erc-faces) > + > + (defface erc-my-nick-prefix-face '((t :weight bold)) > + "ERC face used for my user mode prefix." > + :group 'erc-faces) Try to use the :inherit property at least to link those two (so users who just want to change the two without making them different only need to change one of the two) and ideally by inheriting from some other face. > + (defun erc-get-user-mode-prefix (user) > + (when user > + (cond ((erc-channel-user-voice-p user) "+") > + ((erc-channel-user-half-op-p user) "%") > + ((erc-channel-user-op-p user) "@") > + ((erc-channel-user-admin-p user) "&") > + ((erc-channel-user-owner-p user) "~") > + (t "")))) Here I assume there's some kind of logic or convention. If not, maybe it would be appropriate to do something like add some `help-echo' property to those extra chars? One more thing: the above suggests that maybe voice/halfop/op/admin/owner are mutually exclusive. Is that the case? Could these be collapsed into a single element which could have values `voice', `halfop', `op', `admin', or `owner' (or nil)? > (defun erc-format-@nick (&optional user channel-data) > "Format the nickname of USER showing if USER is an operator or has voice. > Operators have \"@\" and users with voice have \"+\" as a prefix. > Use CHANNEL-DATA to determine op and voice status. > See also `erc-format-nick-function'." > (when user > ! (let ((nick (erc-server-user-nickname user))) > ! (concat (erc-propertize (erc-get-user-mode-prefix nick) 'face 'erc-nick-prefix-face) nick)))) Please try to stay with 80 columns. BTW, IIUC, ERC is not distributed separately from Emacs any more, so we don't need to use compatibility crutches like erc-propertize any more (tho it's fine to use it as well for now, and it could be removed "all at once" in another patch). > ! "(ov)@+")) [...] > ! "(qaohv)~&@%+")) Yay! Magic! > ! (let (prefix op-ch voice-ch names name op voice) > (setq prefix (erc-parse-prefix)) > ! (setq op-ch (cdr (assq ?o prefix)) > ! voice-ch (cdr (assq ?v prefix))) this should have been (let* ((prefix (erc-parse-prefix)) (op-ch (cdr (assq ?o prefix))) (voice-ch (cdr (assq ?v prefix))) names name op voice) Which is both cleaner and faster. So when you change such code, you can take advantage of the change to try and reduce occurrences of those "let-without-init followed by setq". > --- 4763,4820 ---- > (if (rassq (elt item 0) prefix) > (cond ((= (length item) 1) > (setq updatep nil)) > + ((eq (elt item 0) voice-ch) > + (setq name (substring item 1) > + op 'off > + voice 'on > + halfop 'off > + admin 'off > + owner 'off)) > + ((eq (elt item 0) hop-ch) > + (setq name (substring item 1) > + op 'off > + voice 'off > + halfop 'on > + admin 'off > + owner 'off)) > ((eq (elt item 0) op-ch) > (setq name (substring item 1) > op 'on > ! voice 'off > ! halfop 'off > ! admin 'off > ! owner 'off)) > ! ((eq (elt item 0) adm-ch) > ! (setq name (substring item 1) > ! op 'off > ! voice 'off > ! halfop 'off > ! admin 'on > ! owner 'off)) > ! ((eq (elt item 0) own-ch) > (setq name (substring item 1) > op 'off > ! voice 'off > ! halfop 'off > ! admin 'off > ! owner 'on)) > (t (setq name (substring item 1) > op 'off > ! voice 'off > ! halfop 'off > ! admin 'off > ! owner 'off))) This also makes it sound like those op/voice/admin/owner are mutually exclusive and should be combined into a single element. Otherwise, please simplify the code with: (setq op 'off voice 'off halfop 'off admin 'off owner 'off) (cond ((eq (elt item 0) voice-ch) (setq name (substring item 1) voice 'on)) [...]) > + (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)))) Won't this cause `changed' to "always" be set to t, since (erc-channel-user-voice cuser) will never be `on' or `off' and hence never be equal to `voice'? Also, instead of using on/off and converting them from&to nil/t, maybe it would be simpler to use nil/t plus a special value (e.g. `:unspecified') for the case where the value is simply not provided. Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-17 16:03 ` Stefan Monnier @ 2014-06-18 14:40 ` Kelvin White 2014-06-18 16:08 ` Kelvin White 2014-06-18 18:32 ` Stefan Monnier 0 siblings, 2 replies; 8+ messages in thread From: Kelvin White @ 2014-06-18 14:40 UTC (permalink / raw) To: Stefan Monnier Cc: Lawrence Mitchell, Michael Olson, 17755, Mario Lang, Diane Murray, Alex Schroeder, Julien Danjou, Francis Litterio, Jorgen Schaefer [-- Attachment #1.1: Type: text/plain, Size: 6814 bytes --] > Thanks, here are some comments on it. I wish someone who has worked on > ERC could say something. I never use(d) IRC and have hence no clue what is > a "user mode prefix", for example. A user mode prefix is referring to a symbol prefixed to your nickname to display to other users that you have a certain user mode. Take "&nickname" for instance. The "&" is the user mode prefix showing you have +a (admin) user mode. > > *************** > > *** 1244,1250 **** > > (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) > > ;; on join, we want to stay in the new channel buffer > > ;;(set-buffer ob) > > (erc-display-message parsed nil buffer str)))))) > > --- 1244,1250 ---- > > (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 nil nil nil host login) > > ;; on join, we want to stay in the new channel buffer > > ;;(set-buffer ob) > > (erc-display-message parsed nil buffer str)))))) > > In my opinion, erc-update-channel-member had too many arguments already. > Maybe some of these args should be combined into an erc-channel-user object? My first approach was to change the erc-channel-user struct to use a list of modes, eliminating some of the args, but it seemed to cause issues elsewhere. I'll revisit this again soon. > > + (defsubst erc-channel-user-owner-p (nick) > > + "Return t if NICK is an owner of the current channel." > > Usually we say "non-nil" rather than "t", unless the callers need to > rely on the return value being t rather than some other non-nil value. Indeed, the callers do rely on the value being t in this case. rather than just non-nil > > + (defface erc-nick-prefix-face '((t :weight bold)) > > + "ERC face used for user mode prefix." > > + :group 'erc-faces) > > + > > + (defface erc-my-nick-prefix-face '((t :weight bold)) > > + "ERC face used for my user mode prefix." > > + :group 'erc-faces) > > Try to use the :inherit property at least to link those two (so users > who just want to change the two without making them different only need > to change one of the two) and ideally by inheriting from some other face. Good idea. I have updated this so each of these two faces inherits from the appropriate nick faces. By default the prefix will be the same color unless these are changed individually. > > + (defun erc-get-user-mode-prefix (user) > > + (when user > > + (cond ((erc-channel-user-voice-p user) "+") > > + ((erc-channel-user-half-op-p user) "%") > > + ((erc-channel-user-op-p user) "@") > > + ((erc-channel-user-admin-p user) "&") > > + ((erc-channel-user-owner-p user) "~") > > + (t "")))) > > Here I assume there's some kind of logic or convention. If not, maybe > it would be appropriate to do something like add some `help-echo' > property to those extra chars? Sure, I've updated the patch to add help-echo props > One more thing: the above suggests that maybe > voice/halfop/op/admin/owner are mutually exclusive. Is that the case? > Could these be collapsed into a single element which could have values > `voice', `halfop', `op', `admin', or `owner' (or nil)? These are actually not mutually exclusive. A user could have all of these modes enabled, but it isn't typical. In that case we only want to display the most valuable. If a user has +vo we want to display @. If a user has +oa we display &. etc. Glad you noticed this though, this should check in reverse order. > > (defun erc-format-@nick (&optional user channel-data) > > "Format the nickname of USER showing if USER is an operator or has voice. > > Operators have \"@\" and users with voice have \"+\" as a prefix. > > Use CHANNEL-DATA to determine op and voice status. > > See also `erc-format-nick-function'." > > (when user > > ! (let ((nick (erc-server-user-nickname user))) > > ! (concat (erc-propertize (erc-get-user-mode-prefix nick) 'face 'erc-nick-prefix-face) nick)))) > Please try to stay with 80 columns. Ok > BTW, IIUC, ERC is not distributed separately from Emacs any more, so we > don't need to use compatibility crutches like erc-propertize any more > (tho it's fine to use it as well for now, and it could be removed "all at > once" in another patch). Good point, I'll clean that up in another patch. > > ! "(ov)@+")) > [...] > > ! "(qaohv)~&@%+")) >Yay! Magic! ;D these are the default user modes > ! (let (prefix op-ch voice-ch names name op voice) > (setq prefix (erc-parse-prefix)) > ! (setq op-ch (cdr (assq ?o prefix)) > ! voice-ch (cdr (assq ?v prefix))) > > this should have been > > (let* ((prefix (erc-parse-prefix)) > (op-ch (cdr (assq ?o prefix))) > (voice-ch (cdr (assq ?v prefix))) > names name op voice) > > Which is both cleaner and faster. > > So when you change such code, you can take advantage of the change to > try and reduce occurrences of those "let-without-init followed by setq". This has been updated, thanks. > This also makes it sound like those op/voice/admin/owner are mutually > exclusive and should be combined into a single element. > Otherwise, please simplify the code with: > (setq op 'off voice 'off halfop 'off admin 'off owner 'off) > (cond > ((eq (elt item 0) voice-ch) > (setq name (substring item 1) > voice 'on)) > [...]) Yes, I agree. I have simplified it. > > + (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)))) > > Won't this cause `changed' to "always" be set to t, since > (erc-channel-user-voice cuser) will never be `on' or `off' and hence > never be equal to `voice'? > Also, instead of using on/off and converting them from&to nil/t, maybe > it would be simpler to use nil/t plus a special value > (e.g. `:unspecified') for the case where the value is simply > not provided. Sure, I will look at revising this in a separate patch. I tried to keep this as simple as possible but I have noticed things like this and others that could be simplified and cleaned up a bit. Attached is the new patch cleaned up per your suggestions. Thanks [-- Attachment #1.2: Type: text/html, Size: 10358 bytes --] [-- Attachment #2: erc-patch.diff --] [-- Type: text/plain, Size: 21151 bytes --] *** projects/emacs/lisp/erc/erc.el 2014-06-18 10:08:15.639519157 -0400 --- projects/emacs-dev/lisp/erc/erc.el 2014-06-18 10:15:41.395718554 -0400 *************** *** 370,376 **** ) (cl-defstruct (erc-channel-user (:type vector) :named) ! op voice ;; Last message time (in the form of the return value of ;; (current-time) ;; --- 370,376 ---- ) (cl-defstruct (erc-channel-user (:type vector) :named) ! voice halfop op admin owner ;; Last message time (in the form of the return value of ;; (current-time) ;; *************** *** 475,480 **** --- 475,496 ---- erc-channel-users) (clrhash erc-channel-users))) + (defsubst erc-channel-user-owner-p (nick) + "Return t if NICK is an owner of the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-owner (cdr cdata)))))) + + (defsubst erc-channel-user-admin-p (nick) + "Return t if NICK is an admin in the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-admin (cdr cdata)))))) + (defsubst erc-channel-user-op-p (nick) "Return t if NICK is an operator in the current channel." (and nick *************** *** 483,488 **** --- 499,512 ---- (and cdata (cdr cdata) (erc-channel-user-op (cdr cdata)))))) + (defsubst erc-channel-user-halfop-p (nick) + "Return t if NICK is a half-operator in the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-halfop (cdr cdata)))))) + (defsubst erc-channel-user-voice-p (nick) "Return t if NICK has voice in the current channel." (and nick *************** *** 1122,1127 **** --- 1146,1159 ---- "ERC default face." :group 'erc-faces) + (defface erc-nick-prefix-face '((t :inherit erc-nick-default-face :weight bold)) + "ERC face used for user mode prefix." + :group 'erc-faces) + + (defface erc-my-nick-prefix-face '((t :inherit erc-my-nick-face :weight bold)) + "ERC face used for my user mode prefix." + :group 'erc-faces) + (defface erc-direct-msg-face '((t :foreground "IndianRed")) "ERC face used for messages you receive in the main erc buffer." :group 'erc-faces) *************** *** 4190,4196 **** (defun erc-format-nick (&optional user _channel-data) "Return the nickname of USER. See also `erc-format-nick-function'." ! (when user (erc-server-user-nickname user))) (defun erc-format-@nick (&optional user channel-data) "Format the nickname of USER showing if USER is an operator or has voice. --- 4222,4245 ---- (defun erc-format-nick (&optional user _channel-data) "Return the nickname of USER. See also `erc-format-nick-function'." ! (let ((nick (erc-server-user-nickname user))) ! (concat (erc-propertize ! (erc-get-user-mode-prefix nick) ! 'face 'erc-nick-prefix-face) nick))) ! ! (defun erc-get-user-mode-prefix (user) ! (when user ! (cond ((erc-channel-user-owner-p user) ! (propertize "~" 'help-echo "owner")) ! ((erc-channel-user-admin-p user) ! (propertize "&" 'help-echo "admin")) ! ((erc-channel-user-op-p user) ! (propertize "@" 'help-echo "operator")) ! ((erc-channel-user-halfop-p user) ! (propertize "%" 'help-echo "half-op")) ! ((erc-channel-user-voice-p user) ! propertize "+" 'help-echo "voice") ! (t "")))) (defun erc-format-@nick (&optional user channel-data) "Format the nickname of USER showing if USER is an operator or has voice. *************** *** 4198,4215 **** Use CHANNEL-DATA to determine op and voice status. See also `erc-format-nick-function'." (when user ! (let ((op (and channel-data (erc-channel-user-op channel-data) "@")) ! (voice (and channel-data (erc-channel-user-voice channel-data) "+"))) ! (concat voice op (erc-server-user-nickname user))))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized." (if erc-show-my-nick ! (let ((open "<") (close "> ") ! (nick (erc-current-nick))) (concat (erc-propertize open 'face 'erc-default-face) (erc-propertize nick 'face 'erc-my-nick-face) (erc-propertize close 'face 'erc-default-face))) (let ((prefix "> ")) --- 4247,4267 ---- Use CHANNEL-DATA to determine op and voice status. See also `erc-format-nick-function'." (when user ! (let ((nick (erc-server-user-nickname user))) ! (concat (erc-propertize ! (erc-get-user-mode-prefix nick) ! 'face 'erc-nick-prefix-face) nick nick)))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized." (if erc-show-my-nick ! (let* ((open "<") (close "> ") ! (nick (erc-current-nick)) ! (mode (erc-get-user-mode-prefix nick))) (concat (erc-propertize open 'face 'erc-default-face) + (erc-propertize mode 'face 'erc-my-nick-prefix-face) (erc-propertize nick 'face 'erc-my-nick-face) (erc-propertize close 'face 'erc-default-face))) (let ((prefix "> ")) *************** *** 4685,4691 **** (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer erc-server-parameters))) ;; provide a sane default ! "(ov)@+")) types chars) (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) (setq types (match-string 1 str) --- 4737,4743 ---- (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer erc-server-parameters))) ;; provide a sane default ! "(qaohv)~&@%+")) types chars) (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) (setq types (match-string 1 str) *************** *** 4705,4744 **** Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." ! (let (prefix op-ch voice-ch names name op voice) ! (setq prefix (erc-parse-prefix)) ! (setq op-ch (cdr (assq ?o prefix)) ! voice-ch (cdr (assq ?v prefix))) ! ;; 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) (let ((updatep t)) (if (rassq (elt item 0) prefix) (cond ((= (length item) 1) (setq updatep nil)) - ((eq (elt item 0) op-ch) - (setq name (substring item 1) - op 'on - voice 'off)) ((eq (elt item 0) voice-ch) (setq name (substring item 1) - op 'off voice 'on)) ! (t (setq name (substring item 1) ! op 'off ! voice 'off))) ! (setq name item ! op 'off ! voice 'off)) (when updatep (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member ! name name t op voice))))) (run-hooks 'erc-channel-members-changed-hook))) (defcustom erc-channel-members-changed-hook nil "This hook is called every time the variable `channel-members' changes. The buffer where the change happened is current while this hook is called." --- 4757,4800 ---- Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." ! (let* ((prefix (erc-parse-prefix)) ! (op-ch (cdr (assq ?o prefix))) ! (voice-ch (cdr (assq ?v prefix))) ! (adm-ch (cdr (assq ?a prefix))) ! (own-ch (cdr (assq ?q prefix))) ! names name op voice halfop admin owner) (setq names (delete "" (split-string names-string))) (let ((erc-channel-members-changed-hook nil)) (dolist (item names) (let ((updatep t)) + (setq name item op 'off voice 'off halfop 'off admin 'off owner 'off) (if (rassq (elt item 0) prefix) (cond ((= (length item) 1) (setq updatep nil)) ((eq (elt item 0) voice-ch) (setq name (substring item 1) voice 'on)) ! ((eq (elt item 0) hop-ch) ! (setq name (substring item 1) ! halfop 'on)) ! ((eq (elt item 0) op-ch) ! (setq name (substring item 1) ! op 'on)) ! ((eq (elt item 0) adm-ch) ! (setq name (substring item 1) ! admin 'on)) ! ((eq (elt item 0) own-ch) ! (setq name (substring item 1) ! owner 'on)) ! (t (setq name (substring item 1))))) (when updatep (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member ! name name t voice halfop op admin owner))))) (run-hooks 'erc-channel-members-changed-hook))) + (defcustom erc-channel-members-changed-hook nil "This hook is called every time the variable `channel-members' changes. The buffer where the change happened is current while this hook is called." *************** *** 4795,4810 **** changed)) (defun erc-update-current-channel-member ! (nick new-nick &optional add op voice host login full-name info update-message-time) "Update 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 the 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). 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 --- 4851,4865 ---- changed)) (defun erc-update-current-channel-member ! (nick new-nick &optional add voice halfop op admin owner host login full-name info update-message-time) "Update 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 VOICE HALFOP OP ADMIN or OWNER ! are non-nil, they must be equal to either `on' or `off', in which ! case the status of the 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). 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 *************** *** 4822,4827 **** --- 4877,4896 ---- (if cuser (progn (erc-log (format "update-member: user = %S, cuser = %S" user cuser)) + (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)))) + (when (and halfop + (not (eq (erc-channel-user-halfop cuser) halfop))) + (setq changed t) + (setf (erc-channel-user-halfop cuser) + (cond ((eq halfop 'on) t) + ((eq halfop 'off) nil) + (t halfop)))) (when (and op (not (eq (erc-channel-user-op cuser) op))) (setq changed t) *************** *** 4829,4841 **** (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)))) (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed --- 4898,4917 ---- (cond ((eq op 'on) t) ((eq op 'off) nil) (t op)))) ! (when (and admin ! (not (eq (erc-channel-user-admin cuser) admin))) (setq changed t) ! (setf (erc-channel-user-admin cuser) ! (cond ((eq admin 'on) t) ! ((eq admin 'off) nil) ! (t admin)))) ! (when (and owner ! (not (eq (erc-channel-user-owner cuser) owner))) ! (setq changed t) ! (setf (erc-channel-user-owner cuser) ! (cond ((eq owner 'on) t) ! ((eq owner 'off) nil) ! (t owner)))) (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed *************** *** 4856,4867 **** (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)) :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) --- 4932,4952 ---- (cons (current-buffer) (erc-server-user-buffers user)))) (setq cuser (make-erc-channel-user :voice (cond ((eq voice 'on) t) ((eq voice 'off) nil) (t voice)) + :halfop (cond ((eq halfop 'on) t) + ((eq halfop 'off) nil) + (t halfop)) + :op (cond ((eq op 'on) t) + ((eq op 'off) nil) + (t op)) + :admin (cond ((eq admin 'on) t) + ((eq admin 'off) nil) + (t admin)) + :owner (cond ((eq owner 'on) t) + ((eq owner 'off) nil) + (t owner)) :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) *************** *** 4872,4878 **** (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick ! &optional add op voice host login full-name info update-message-time) "Update user and channel information for the user with nickname NICK in channel CHANNEL. --- 4957,4963 ---- (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick ! &optional add voice halfop op admin owner host login full-name info update-message-time) "Update user and channel information for the user with nickname NICK in channel CHANNEL. *************** *** 4880,4886 **** See also: `erc-update-current-channel-member'." (erc-with-buffer (channel) ! (erc-update-current-channel-member nick new-nick add op voice host login full-name info update-message-time))) --- 4965,4971 ---- See also: `erc-update-current-channel-member'." (erc-with-buffer (channel) ! (erc-update-current-channel-member nick new-nick add voice halfop op admin owner host login full-name info update-message-time))) *************** *** 4979,4985 **** (while chars (cond ((string= (car chars) "+") (setq add-p t)) ((string= (car chars) "-") (setq add-p nil)) ! ((string-match "^[ovbOVB]" (car chars)) (setq arg-modes (cons (list (car chars) (if add-p 'on 'off) (if args (car args) nil)) --- 5064,5070 ---- (while chars (cond ((string= (car chars) "+") (setq add-p t)) ((string= (car chars) "-") (setq add-p nil)) ! ((string-match "^[qaovhbQAOVHB]" (car chars)) (setq arg-modes (cons (list (car chars) (if add-p 'on 'off) (if args (car args) nil)) *************** *** 5035,5045 **** (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) --- 5120,5135 ---- (let ((mode (nth 0 (car arg-modes))) (onoff (nth 1 (car arg-modes))) (arg (nth 2 (car arg-modes)))) ! (cond ((string-match "^[Vv]" mode) (erc-update-channel-member tgt arg arg nil onoff)) ! ((string-match "^[hH]" mode) ! (erc-update-channel-member tgt arg arg nil nil onoff)) ! ((string-match "^[oO]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil onoff)) ! ((string-match "^[aA]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil nil onoff)) ! ((string-match "^[qQ]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil nil nil onoff)) ((string-match "^[Ll]" mode) (erc-update-channel-limit tgt onoff arg)) ((string-match "^[Kk]" mode) *************** *** 5978,6003 **** (user (if channel-data (car channel-data) (erc-get-server-user word))) ! host login full-name nick op voice) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) login (erc-server-user-login user) full-name (erc-server-user-full-name user)) (if cuser ! (setq op (erc-channel-user-op cuser) ! voice (erc-channel-user-voice cuser))) (if (called-interactively-p 'interactive) (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)) "")) ! user)))) (defun erc-away-time () "Return non-nil if the current ERC process is set away. --- 6068,6099 ---- (user (if channel-data (car channel-data) (erc-get-server-user word))) ! host login full-name nick voice halfop op admin owner) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) login (erc-server-user-login user) full-name (erc-server-user-full-name user)) (if cuser ! (setq voice (erc-channel-user-voice cuser) ! halfop (erc-channel-user-halfop cuser) ! op (erc-channel-user-op cuser) ! admin (erc-channel-user-admin cuser) ! owner (erc-channel-user-owner cuser)))) (if (called-interactively-p 'interactive) (message "%s is %s@%s%s%s" nick login host (if full-name (format " (%s)" full-name) "") ! (if (or voice halfop op admin owner) (format " and is +%s%s on %s" (if voice "v" "") + (if halfop "h" "") + (if op "o" "") + (if admin "a" "") + (if owner "q" "") (erc-default-target)) "")) ! user))) (defun erc-away-time () "Return non-nil if the current ERC process is set away. ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-18 14:40 ` Kelvin White @ 2014-06-18 16:08 ` Kelvin White 2014-06-18 18:32 ` Stefan Monnier 1 sibling, 0 replies; 8+ messages in thread From: Kelvin White @ 2014-06-18 16:08 UTC (permalink / raw) To: Stefan Monnier Cc: Lawrence Mitchell, Michael Olson, 17755, Mario Lang, Diane Murray, Alex Schroeder, Julien Danjou, Francis Litterio, Jorgen Schaefer [-- Attachment #1.1: Type: text/plain, Size: 7343 bytes --] Apologies, I just realized I didn't include the whole patch in the last submission. Here is the entire diff. On Wed, Jun 18, 2014 at 10:40 AM, Kelvin White <kelvin.white77@gmail.com> wrote: > > Thanks, here are some comments on it. I wish someone who has worked on > > ERC could say something. I never use(d) IRC and have hence no clue what > is > > a "user mode prefix", for example. > > A user mode prefix is referring to a symbol prefixed to your nickname to > display to other users that you have a certain user mode. > Take "&nickname" for instance. The "&" is the user mode prefix showing you > have +a (admin) user mode. > > > > *************** > > > *** 1244,1250 **** > > > (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) > > > ;; on join, we want to stay in the new channel buffer > > > ;;(set-buffer ob) > > > (erc-display-message parsed nil buffer str)))))) > > > --- 1244,1250 ---- > > > (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 nil > nil nil host login) > > > ;; on join, we want to stay in the new channel buffer > > > ;;(set-buffer ob) > > > (erc-display-message parsed nil buffer str)))))) > > > > In my opinion, erc-update-channel-member had too many arguments already. > > Maybe some of these args should be combined into an erc-channel-user > object? > > My first approach was to change the erc-channel-user struct to use a list > of modes, > eliminating some of the args, but it seemed to cause issues elsewhere. > I'll revisit this again soon. > > > > + (defsubst erc-channel-user-owner-p (nick) > > > + "Return t if NICK is an owner of the current channel." > > > > Usually we say "non-nil" rather than "t", unless the callers need to > > rely on the return value being t rather than some other non-nil value. > > Indeed, the callers do rely on the value being t in this case. rather than > just non-nil > > > > + (defface erc-nick-prefix-face '((t :weight bold)) > > > + "ERC face used for user mode prefix." > > > + :group 'erc-faces) > > > + > > > + (defface erc-my-nick-prefix-face '((t :weight bold)) > > > + "ERC face used for my user mode prefix." > > > + :group 'erc-faces) > > > > Try to use the :inherit property at least to link those two (so users > > who just want to change the two without making them different only need > > to change one of the two) and ideally by inheriting from some other face. > > Good idea. I have updated this so each of these two faces inherits from > the appropriate nick faces. > By default the prefix will be the same color unless these are changed > individually. > > > > + (defun erc-get-user-mode-prefix (user) > > > + (when user > > > + (cond ((erc-channel-user-voice-p user) "+") > > > + ((erc-channel-user-half-op-p user) "%") > > > + ((erc-channel-user-op-p user) "@") > > > + ((erc-channel-user-admin-p user) "&") > > > + ((erc-channel-user-owner-p user) "~") > > > + (t "")))) > > > > Here I assume there's some kind of logic or convention. If not, maybe > > it would be appropriate to do something like add some `help-echo' > > property to those extra chars? > > Sure, I've updated the patch to add help-echo props > > > One more thing: the above suggests that maybe > > voice/halfop/op/admin/owner are mutually exclusive. Is that the case? > > Could these be collapsed into a single element which could have values > > `voice', `halfop', `op', `admin', or `owner' (or nil)? > > These are actually not mutually exclusive. A user could have all of these > modes enabled, but it isn't typical. > In that case we only want to display the most valuable. If a user has +vo > we want to display @. > If a user has +oa we display &. etc. Glad you noticed this though, this > should check in reverse order. > > > > (defun erc-format-@nick (&optional user channel-data) > > > "Format the nickname of USER showing if USER is an operator or has > voice. > > > Operators have \"@\" and users with voice have \"+\" as a prefix. > > > Use CHANNEL-DATA to determine op and voice status. > > > See also `erc-format-nick-function'." > > > (when user > > > ! (let ((nick (erc-server-user-nickname user))) > > > ! (concat (erc-propertize (erc-get-user-mode-prefix nick) 'face > 'erc-nick-prefix-face) nick)))) > > > Please try to stay with 80 columns. > > Ok > > > BTW, IIUC, ERC is not distributed separately from Emacs any more, so we > > don't need to use compatibility crutches like erc-propertize any more > > (tho it's fine to use it as well for now, and it could be removed "all at > > once" in another patch). > > Good point, I'll clean that up in another patch. > > > > ! "(ov)@+")) > > [...] > > > ! "(qaohv)~&@%+")) > > >Yay! Magic! > > ;D these are the default user modes > > > ! (let (prefix op-ch voice-ch names name op voice) > > (setq prefix (erc-parse-prefix)) > > ! (setq op-ch (cdr (assq ?o prefix)) > > ! voice-ch (cdr (assq ?v prefix))) > > > > this should have been > > > > (let* ((prefix (erc-parse-prefix)) > > (op-ch (cdr (assq ?o prefix))) > > (voice-ch (cdr (assq ?v prefix))) > > names name op voice) > > > > Which is both cleaner and faster. > > > > So when you change such code, you can take advantage of the change to > > try and reduce occurrences of those "let-without-init followed by setq". > > This has been updated, thanks. > > > This also makes it sound like those op/voice/admin/owner are mutually > > exclusive and should be combined into a single element. > > > Otherwise, please simplify the code with: > > > (setq op 'off voice 'off halfop 'off admin 'off owner 'off) > > (cond > > ((eq (elt item 0) voice-ch) > > (setq name (substring item 1) > > voice 'on)) > > [...]) > > Yes, I agree. I have simplified it. > > > > + (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)))) > > > > Won't this cause `changed' to "always" be set to t, since > > (erc-channel-user-voice cuser) will never be `on' or `off' and hence > > never be equal to `voice'? > > > Also, instead of using on/off and converting them from&to nil/t, maybe > > it would be simpler to use nil/t plus a special value > > (e.g. `:unspecified') for the case where the value is simply > > not provided. > > Sure, I will look at revising this in a separate patch. I tried to keep > this as simple > as possible but I have noticed things like this and others that could be > simplified > and cleaned up a bit. > > Attached is the new patch cleaned up per your suggestions. > > Thanks > > [-- Attachment #1.2: Type: text/html, Size: 11207 bytes --] [-- Attachment #2: erc-patch.diff --] [-- Type: text/plain, Size: 30179 bytes --] diff --ignore-space-change -c '-F^[_a-zA-Z0-9$]+ *(' projects/emacs/lisp/erc/ChangeLog projects/emacs-dev/lisp/erc/ChangeLog *** projects/emacs/lisp/erc/ChangeLog 2014-06-13 10:21:10.232494842 -0400 --- projects/emacs-dev/lisp/erc/ChangeLog 2014-06-18 12:06:37.222399565 -0400 *************** *** 1,3 **** --- 1,15 ---- + 2014-06-11 Kelvin White <kelvin.white77@gmail.com> + + * erc-backend.el: Handle user modes in relevent server responses + * erc.el: Better user mode support. + (erc-channel-user): Add members for new modes. + (erc-channel-member-halfop-p, erc-channel-user-admin-p, erc-channel-user-owner-p): Use new struct members. + (erc-format-nick, erc-format-@nick): Display user modes as nick prefix. + (erc-nick-prefix-face, erc-my-nick-prefix-face): Add new faces to separate colors if desired. + (erc-get-user-mode-prefix): Return symbol for mode prefix. + (erc-update-channel-member, erc-update-current-channel-member, erc-channel-receive-names): Update channel users. + (erc-nick-at-point): Return correct user info. + 2014-04-04 Stefan Monnier <monnier@iro.umontreal.ca> * erc.el (erc-invite-only-mode, erc-toggle-channel-mode): Simplify. *************** *** 615,618 **** ;; coding: utf-8 ;; add-log-time-zone-rule: t ;; End: - --- 627,629 ---- diff --ignore-space-change -c '-F^[_a-zA-Z0-9$]+ *(' projects/emacs/lisp/erc/erc-backend.el projects/emacs-dev/lisp/erc/erc-backend.el *** projects/emacs/lisp/erc/erc-backend.el 2014-06-13 10:21:10.235828074 -0400 --- projects/emacs-dev/lisp/erc/erc-backend.el 2014-06-18 12:04:21.716635854 -0400 *************** *** 5,11 **** ;; Filename: erc-backend.el ;; Author: Lawrence Mitchell <wence@gmx.li> ;; Maintainer: emacs-devel@gnu.org ! ;; Created: 2004-05-7 ;; Keywords: IRC chat client internet ;; This file is part of GNU Emacs. --- 5,13 ---- ;; Filename: erc-backend.el ;; Author: Lawrence Mitchell <wence@gmx.li> ;; Maintainer: emacs-devel@gnu.org ! ;; Hacker: l3thal@smashthestack.org ! ;; Created: 2004-05-07 ! ;; Hacked: 2014-06-08 ;; Keywords: IRC chat client internet ;; This file is part of GNU Emacs. *************** *** 1208,1216 **** parsed 'notice 'active 'INVITE ?n nick ?u login ?h host ?c chnl))))) ! (define-erc-response-handler (JOIN) ! "Handle join messages." nil (let ((chnl (erc-response.contents parsed)) (buffer nil)) --- 1210,1218 ---- parsed 'notice 'active 'INVITE ?n nick ?u login ?h host ?c chnl))))) ! ;;; hacked (define-erc-response-handler (JOIN) ! "HACKED: Handle join messages." nil (let ((chnl (erc-response.contents parsed)) (buffer nil)) *************** *** 1244,1250 **** (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) ;; on join, we want to stay in the new channel buffer ;;(set-buffer ob) (erc-display-message parsed nil buffer str)))))) --- 1246,1252 ---- (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 nil nil nil host login) ;; on join, we want to stay in the new channel buffer ;;(set-buffer ob) (erc-display-message parsed nil buffer str)))))) *************** *** 1385,1392 **** ?s (if (/= erc-server-lag 1) "s" ""))) (erc-update-mode-line)))) (define-erc-response-handler (PRIVMSG NOTICE) ! "Handle private messages, including messages in channels." nil (let ((sender-spec (erc-response.sender parsed)) (cmd (erc-response.command parsed)) (tgt (car (erc-response.command-args parsed))) --- 1387,1395 ---- ?s (if (/= erc-server-lag 1) "s" ""))) (erc-update-mode-line)))) + ;;; hacked (define-erc-response-handler (PRIVMSG NOTICE) ! "HACKED: Handle private messages, including messages in channels." nil (let ((sender-spec (erc-response.sender parsed)) (cmd (erc-response.command parsed)) (tgt (car (erc-response.command-args parsed))) *************** *** 1413,1419 **** ;; 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) (let ((cdata (erc-get-channel-user nick))) (setq fnick (funcall erc-format-nick-function (car cdata) (cdr cdata)))))) --- 1416,1422 ---- ;; message. We will accumulate private identities indefinitely ;; at this point. (erc-update-channel-member (if privp nick tgt) nick nick ! privp nil nil nil nil nil host login nil nil t) (let ((cdata (erc-get-channel-user nick))) (setq fnick (funcall erc-format-nick-function (car cdata) (cdr cdata)))))) *************** *** 1461,1476 **** (erc-display-message parsed 'notice bufs 'QUIT ?n nick ?u login ?h host ?r reason)))) ! (define-erc-response-handler (TOPIC) ! "The channel topic has changed." nil (let* ((ch (car (erc-response.command-args parsed))) (topic (erc-trim-string (erc-response.contents parsed))) (time (format-time-string erc-server-timestamp-format (current-time)))) (pcase-let ((`(,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-topic ch (format "%s\C-o (%s, %s)" topic nick time)) (erc-display-message parsed 'notice (erc-get-buffer ch proc) 'TOPIC ?n nick ?u login ?h host --- 1464,1479 ---- (erc-display-message parsed 'notice bufs 'QUIT ?n nick ?u login ?h host ?r reason)))) ! ;;; hacked (define-erc-response-handler (TOPIC) ! "HACKED: The channel topic has changed." nil (let* ((ch (car (erc-response.command-args parsed))) (topic (erc-trim-string (erc-response.contents parsed))) (time (format-time-string erc-server-timestamp-format (current-time)))) (pcase-let ((`(,nick ,login ,host) (erc-parse-user (erc-response.sender parsed)))) ! (erc-update-channel-member ch nick nick nil nil nil nil nil nil host login) (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time)) (erc-display-message parsed 'notice (erc-get-buffer ch proc) 'TOPIC ?n nick ?u login ?h host *************** *** 1791,1798 **** (erc-display-message parsed 'notice (erc-get-buffer channel proc) 's341 ?n nick ?c channel))) (define-erc-response-handler (352) ! "WHO notice." nil (pcase-let ((`(,channel ,user ,host ,server ,nick ,away-flag) (cdr (erc-response.command-args parsed)))) (let ((full-name (erc-response.contents parsed)) --- 1794,1802 ---- (erc-display-message parsed 'notice (erc-get-buffer channel proc) 's341 ?n nick ?c channel))) + ;;; hacked (define-erc-response-handler (352) ! "HACKED: WHO notice." nil (pcase-let ((`(,channel ,user ,host ,server ,nick ,away-flag) (cdr (erc-response.command-args parsed)))) (let ((full-name (erc-response.contents parsed)) *************** *** 1800,1807 **** (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name) (setq hopcount (match-string 1 full-name)) (setq full-name (match-string 2 full-name))) ! (erc-update-channel-member channel nick nick nil nil nil host ! user full-name) (erc-display-message parsed 'notice 'active 's352 ?c channel ?n nick ?a away-flag ?u user ?h host ?f full-name)))) --- 1804,1810 ---- (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name) (setq hopcount (match-string 1 full-name)) (setq full-name (match-string 2 full-name))) ! (erc-update-channel-member channel nick nick nil nil nil nil nil nil host user full-name) (erc-display-message parsed 'notice 'active 's352 ?c channel ?n nick ?a away-flag ?u user ?h host ?f full-name)))) diff --ignore-space-change -c '-F^[_a-zA-Z0-9$]+ *(' projects/emacs/lisp/erc/erc.el projects/emacs-dev/lisp/erc/erc.el *** projects/emacs/lisp/erc/erc.el 2014-06-18 10:08:15.639519157 -0400 --- projects/emacs-dev/lisp/erc/erc.el 2014-06-18 10:15:41.395718554 -0400 *************** *** 370,376 **** ) (cl-defstruct (erc-channel-user (:type vector) :named) ! op voice ;; Last message time (in the form of the return value of ;; (current-time) ;; --- 370,376 ---- ) (cl-defstruct (erc-channel-user (:type vector) :named) ! voice halfop op admin owner ;; Last message time (in the form of the return value of ;; (current-time) ;; *************** *** 475,480 **** --- 475,496 ---- erc-channel-users) (clrhash erc-channel-users))) + (defsubst erc-channel-user-owner-p (nick) + "Return t if NICK is an owner of the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-owner (cdr cdata)))))) + + (defsubst erc-channel-user-admin-p (nick) + "Return t if NICK is an admin in the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-admin (cdr cdata)))))) + (defsubst erc-channel-user-op-p (nick) "Return t if NICK is an operator in the current channel." (and nick *************** *** 483,488 **** --- 499,512 ---- (and cdata (cdr cdata) (erc-channel-user-op (cdr cdata)))))) + (defsubst erc-channel-user-halfop-p (nick) + "Return t if NICK is a half-operator in the current channel." + (and nick + (hash-table-p erc-channel-users) + (let ((cdata (erc-get-channel-user nick))) + (and cdata (cdr cdata) + (erc-channel-user-halfop (cdr cdata)))))) + (defsubst erc-channel-user-voice-p (nick) "Return t if NICK has voice in the current channel." (and nick *************** *** 1122,1127 **** --- 1146,1159 ---- "ERC default face." :group 'erc-faces) + (defface erc-nick-prefix-face '((t :inherit erc-nick-default-face :weight bold)) + "ERC face used for user mode prefix." + :group 'erc-faces) + + (defface erc-my-nick-prefix-face '((t :inherit erc-my-nick-face :weight bold)) + "ERC face used for my user mode prefix." + :group 'erc-faces) + (defface erc-direct-msg-face '((t :foreground "IndianRed")) "ERC face used for messages you receive in the main erc buffer." :group 'erc-faces) *************** *** 4190,4196 **** (defun erc-format-nick (&optional user _channel-data) "Return the nickname of USER. See also `erc-format-nick-function'." ! (when user (erc-server-user-nickname user))) (defun erc-format-@nick (&optional user channel-data) "Format the nickname of USER showing if USER is an operator or has voice. --- 4222,4245 ---- (defun erc-format-nick (&optional user _channel-data) "Return the nickname of USER. See also `erc-format-nick-function'." ! (let ((nick (erc-server-user-nickname user))) ! (concat (erc-propertize ! (erc-get-user-mode-prefix nick) ! 'face 'erc-nick-prefix-face) nick))) ! ! (defun erc-get-user-mode-prefix (user) ! (when user ! (cond ((erc-channel-user-owner-p user) ! (propertize "~" 'help-echo "owner")) ! ((erc-channel-user-admin-p user) ! (propertize "&" 'help-echo "admin")) ! ((erc-channel-user-op-p user) ! (propertize "@" 'help-echo "operator")) ! ((erc-channel-user-halfop-p user) ! (propertize "%" 'help-echo "half-op")) ! ((erc-channel-user-voice-p user) ! propertize "+" 'help-echo "voice") ! (t "")))) (defun erc-format-@nick (&optional user channel-data) "Format the nickname of USER showing if USER is an operator or has voice. *************** *** 4198,4215 **** Use CHANNEL-DATA to determine op and voice status. See also `erc-format-nick-function'." (when user ! (let ((op (and channel-data (erc-channel-user-op channel-data) "@")) ! (voice (and channel-data (erc-channel-user-voice channel-data) "+"))) ! (concat voice op (erc-server-user-nickname user))))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized." (if erc-show-my-nick ! (let ((open "<") (close "> ") ! (nick (erc-current-nick))) (concat (erc-propertize open 'face 'erc-default-face) (erc-propertize nick 'face 'erc-my-nick-face) (erc-propertize close 'face 'erc-default-face))) (let ((prefix "> ")) --- 4247,4267 ---- Use CHANNEL-DATA to determine op and voice status. See also `erc-format-nick-function'." (when user ! (let ((nick (erc-server-user-nickname user))) ! (concat (erc-propertize ! (erc-get-user-mode-prefix nick) ! 'face 'erc-nick-prefix-face) nick nick)))) (defun erc-format-my-nick () "Return the beginning of this user's message, correctly propertized." (if erc-show-my-nick ! (let* ((open "<") (close "> ") ! (nick (erc-current-nick)) ! (mode (erc-get-user-mode-prefix nick))) (concat (erc-propertize open 'face 'erc-default-face) + (erc-propertize mode 'face 'erc-my-nick-prefix-face) (erc-propertize nick 'face 'erc-my-nick-face) (erc-propertize close 'face 'erc-default-face))) (let ((prefix "> ")) *************** *** 4685,4691 **** (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer erc-server-parameters))) ;; provide a sane default ! "(ov)@+")) types chars) (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) (setq types (match-string 1 str) --- 4737,4743 ---- (let ((str (or (cdr (assoc "PREFIX" (erc-with-server-buffer erc-server-parameters))) ;; provide a sane default ! "(qaohv)~&@%+")) types chars) (when (string-match "^(\\([^)]+\\))\\(.+\\)$" str) (setq types (match-string 1 str) *************** *** 4705,4744 **** Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." ! (let (prefix op-ch voice-ch names name op voice) ! (setq prefix (erc-parse-prefix)) ! (setq op-ch (cdr (assq ?o prefix)) ! voice-ch (cdr (assq ?v prefix))) ! ;; 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) (let ((updatep t)) (if (rassq (elt item 0) prefix) (cond ((= (length item) 1) (setq updatep nil)) - ((eq (elt item 0) op-ch) - (setq name (substring item 1) - op 'on - voice 'off)) ((eq (elt item 0) voice-ch) (setq name (substring item 1) - op 'off voice 'on)) ! (t (setq name (substring item 1) ! op 'off ! voice 'off))) ! (setq name item ! op 'off ! voice 'off)) (when updatep (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member ! name name t op voice))))) (run-hooks 'erc-channel-members-changed-hook))) (defcustom erc-channel-members-changed-hook nil "This hook is called every time the variable `channel-members' changes. The buffer where the change happened is current while this hook is called." --- 4757,4800 ---- Update `erc-channel-users' according to NAMES-STRING. NAMES-STRING is a string listing some of the names on the channel." ! (let* ((prefix (erc-parse-prefix)) ! (op-ch (cdr (assq ?o prefix))) ! (voice-ch (cdr (assq ?v prefix))) ! (adm-ch (cdr (assq ?a prefix))) ! (own-ch (cdr (assq ?q prefix))) ! names name op voice halfop admin owner) (setq names (delete "" (split-string names-string))) (let ((erc-channel-members-changed-hook nil)) (dolist (item names) (let ((updatep t)) + (setq name item op 'off voice 'off halfop 'off admin 'off owner 'off) (if (rassq (elt item 0) prefix) (cond ((= (length item) 1) (setq updatep nil)) ((eq (elt item 0) voice-ch) (setq name (substring item 1) voice 'on)) ! ((eq (elt item 0) hop-ch) ! (setq name (substring item 1) ! halfop 'on)) ! ((eq (elt item 0) op-ch) ! (setq name (substring item 1) ! op 'on)) ! ((eq (elt item 0) adm-ch) ! (setq name (substring item 1) ! admin 'on)) ! ((eq (elt item 0) own-ch) ! (setq name (substring item 1) ! owner 'on)) ! (t (setq name (substring item 1))))) (when updatep (puthash (erc-downcase name) t erc-channel-new-member-names) (erc-update-current-channel-member ! name name t voice halfop op admin owner))))) (run-hooks 'erc-channel-members-changed-hook))) + (defcustom erc-channel-members-changed-hook nil "This hook is called every time the variable `channel-members' changes. The buffer where the change happened is current while this hook is called." *************** *** 4795,4810 **** changed)) (defun erc-update-current-channel-member ! (nick new-nick &optional add op voice host login full-name info update-message-time) "Update 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 the 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). 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 --- 4851,4865 ---- changed)) (defun erc-update-current-channel-member ! (nick new-nick &optional add voice halfop op admin owner host login full-name info update-message-time) "Update 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 VOICE HALFOP OP ADMIN or OWNER ! are non-nil, they must be equal to either `on' or `off', in which ! case the status of the 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). 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 *************** *** 4822,4827 **** --- 4877,4896 ---- (if cuser (progn (erc-log (format "update-member: user = %S, cuser = %S" user cuser)) + (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)))) + (when (and halfop + (not (eq (erc-channel-user-halfop cuser) halfop))) + (setq changed t) + (setf (erc-channel-user-halfop cuser) + (cond ((eq halfop 'on) t) + ((eq halfop 'off) nil) + (t halfop)))) (when (and op (not (eq (erc-channel-user-op cuser) op))) (setq changed t) *************** *** 4829,4841 **** (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)))) (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed --- 4898,4917 ---- (cond ((eq op 'on) t) ((eq op 'off) nil) (t op)))) ! (when (and admin ! (not (eq (erc-channel-user-admin cuser) admin))) (setq changed t) ! (setf (erc-channel-user-admin cuser) ! (cond ((eq admin 'on) t) ! ((eq admin 'off) nil) ! (t admin)))) ! (when (and owner ! (not (eq (erc-channel-user-owner cuser) owner))) ! (setq changed t) ! (setf (erc-channel-user-owner cuser) ! (cond ((eq owner 'on) t) ! ((eq owner 'off) nil) ! (t owner)))) (when update-message-time (setf (erc-channel-user-last-message-time cuser) (current-time))) (setq user-changed *************** *** 4856,4867 **** (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)) :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) --- 4932,4952 ---- (cons (current-buffer) (erc-server-user-buffers user)))) (setq cuser (make-erc-channel-user :voice (cond ((eq voice 'on) t) ((eq voice 'off) nil) (t voice)) + :halfop (cond ((eq halfop 'on) t) + ((eq halfop 'off) nil) + (t halfop)) + :op (cond ((eq op 'on) t) + ((eq op 'off) nil) + (t op)) + :admin (cond ((eq admin 'on) t) + ((eq admin 'off) nil) + (t admin)) + :owner (cond ((eq owner 'on) t) + ((eq owner 'off) nil) + (t owner)) :last-message-time (if update-message-time (current-time)))) (puthash (erc-downcase nick) (cons user cuser) *************** *** 4872,4878 **** (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick ! &optional add op voice host login full-name info update-message-time) "Update user and channel information for the user with nickname NICK in channel CHANNEL. --- 4957,4963 ---- (or changed user-changed add))) (defun erc-update-channel-member (channel nick new-nick ! &optional add voice halfop op admin owner host login full-name info update-message-time) "Update user and channel information for the user with nickname NICK in channel CHANNEL. *************** *** 4880,4886 **** See also: `erc-update-current-channel-member'." (erc-with-buffer (channel) ! (erc-update-current-channel-member nick new-nick add op voice host login full-name info update-message-time))) --- 4965,4971 ---- See also: `erc-update-current-channel-member'." (erc-with-buffer (channel) ! (erc-update-current-channel-member nick new-nick add voice halfop op admin owner host login full-name info update-message-time))) *************** *** 4979,4985 **** (while chars (cond ((string= (car chars) "+") (setq add-p t)) ((string= (car chars) "-") (setq add-p nil)) ! ((string-match "^[ovbOVB]" (car chars)) (setq arg-modes (cons (list (car chars) (if add-p 'on 'off) (if args (car args) nil)) --- 5064,5070 ---- (while chars (cond ((string= (car chars) "+") (setq add-p t)) ((string= (car chars) "-") (setq add-p nil)) ! ((string-match "^[qaovhbQAOVHB]" (car chars)) (setq arg-modes (cons (list (car chars) (if add-p 'on 'off) (if args (car args) nil)) *************** *** 5035,5045 **** (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) --- 5120,5135 ---- (let ((mode (nth 0 (car arg-modes))) (onoff (nth 1 (car arg-modes))) (arg (nth 2 (car arg-modes)))) ! (cond ((string-match "^[Vv]" mode) (erc-update-channel-member tgt arg arg nil onoff)) ! ((string-match "^[hH]" mode) ! (erc-update-channel-member tgt arg arg nil nil onoff)) ! ((string-match "^[oO]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil onoff)) ! ((string-match "^[aA]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil nil onoff)) ! ((string-match "^[qQ]" mode) ! (erc-update-channel-member tgt arg arg nil nil nil nil nil onoff)) ((string-match "^[Ll]" mode) (erc-update-channel-limit tgt onoff arg)) ((string-match "^[Kk]" mode) *************** *** 5978,6003 **** (user (if channel-data (car channel-data) (erc-get-server-user word))) ! host login full-name nick op voice) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) login (erc-server-user-login user) full-name (erc-server-user-full-name user)) (if cuser ! (setq op (erc-channel-user-op cuser) ! voice (erc-channel-user-voice cuser))) (if (called-interactively-p 'interactive) (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)) "")) ! user)))) (defun erc-away-time () "Return non-nil if the current ERC process is set away. --- 6068,6099 ---- (user (if channel-data (car channel-data) (erc-get-server-user word))) ! host login full-name nick voice halfop op admin owner) (when user (setq nick (erc-server-user-nickname user) host (erc-server-user-host user) login (erc-server-user-login user) full-name (erc-server-user-full-name user)) (if cuser ! (setq voice (erc-channel-user-voice cuser) ! halfop (erc-channel-user-halfop cuser) ! op (erc-channel-user-op cuser) ! admin (erc-channel-user-admin cuser) ! owner (erc-channel-user-owner cuser)))) (if (called-interactively-p 'interactive) (message "%s is %s@%s%s%s" nick login host (if full-name (format " (%s)" full-name) "") ! (if (or voice halfop op admin owner) (format " and is +%s%s on %s" (if voice "v" "") + (if halfop "h" "") + (if op "o" "") + (if admin "a" "") + (if owner "q" "") (erc-default-target)) "")) ! user))) (defun erc-away-time () "Return non-nil if the current ERC process is set away. ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-18 14:40 ` Kelvin White 2014-06-18 16:08 ` Kelvin White @ 2014-06-18 18:32 ` Stefan Monnier 2014-06-18 18:51 ` Kelvin White 1 sibling, 1 reply; 8+ messages in thread From: Stefan Monnier @ 2014-06-18 18:32 UTC (permalink / raw) To: Kelvin White Cc: Lawrence Mitchell, Michael Olson, 17755, Mario Lang, Diane Murray, Alex Schroeder, Julien Danjou, Francis Litterio, Jorgen Schaefer >> > + (defsubst erc-channel-user-owner-p (nick) >> > + "Return t if NICK is an owner of the current channel." >> Usually we say "non-nil" rather than "t", unless the callers need to >> rely on the return value being t rather than some other non-nil value. > Indeed, the callers do rely on the value being t in this case. rather than > just non-nil Hmm? I see only one call to erc-channel-user-owner-p and the result is passed to `cond' so any non-nil value will work as well (which is the way it should be for functions named `<foo>-p'). > + 2014-06-11 Kelvin White <kelvin.white77@gmail.com> > + > + * erc-backend.el: Handle user modes in relevent server responses > + * erc.el: Better user mode support. > + (erc-channel-user): Add members for new modes. > + (erc-channel-member-halfop-p, erc-channel-user-admin-p, erc-channel-user-owner-p): Use new struct members. > + (erc-format-nick, erc-format-@nick): Display user modes as nick prefix. > + (erc-nick-prefix-face, erc-my-nick-prefix-face): Add new faces to separate colors if desired. > + (erc-get-user-mode-prefix): Return symbol for mode prefix. > + (erc-update-channel-member, erc-update-current-channel-member, erc-channel-receive-names): Update channel users. > + (erc-nick-at-point): Return correct user info. > + Please try a bit harder to stay within 80 columns. M-q is your friend. > ! ;; Hacker: l3thal@smashthestack.org > ! ;; Created: 2004-05-07 > ! ;; Hacked: 2014-06-08 If you want to add your name, add it to the "Author:" part (one per line, see in erc.el for an example). And don't add entries like timestamps of when it was last changed. This just causes spurious conflicts when merging branches. This info is readily available via "bzr log". I tolerate things like "Created" (tho find it a waste of perfectly good bits and screen real estate) because, by nature these should never change and hence don't cause such spurious conflicts. > ! ;;; hacked > (define-erc-response-handler (JOIN) > ! "HACKED: Handle join messages." What does this "hacked" mean here? Looks like left-over annotations you used temporarily to keep track of what you changed. Anyway, the patch looks OK to me. As soon as your copyright paperwork comes through I can give you write access and you can install it. Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-18 18:32 ` Stefan Monnier @ 2014-06-18 18:51 ` Kelvin White 0 siblings, 0 replies; 8+ messages in thread From: Kelvin White @ 2014-06-18 18:51 UTC (permalink / raw) To: Stefan Monnier Cc: Lawrence Mitchell, Michael Olson, 17755, Mario Lang, Diane Murray, Alex Schroeder, Kelvin White, Julien Danjou, Francis Litterio, Jorgen Schaefer At Wed, 18 Jun 2014 14:32:09 -0400, Stefan Monnier wrote: > > >> > + (defsubst erc-channel-user-owner-p (nick) > >> > + "Return t if NICK is an owner of the current channel." > >> Usually we say "non-nil" rather than "t", unless the callers need to > >> rely on the return value being t rather than some other non-nil value. > > Indeed, the callers do rely on the value being t in this case. rather than > > just non-nil > > Hmm? I see only one call to erc-channel-user-owner-p and the result is > passed to `cond' so any non-nil value will work as well (which is the > way it should be for functions named `<foo>-p'). > You are right, this could be non-nil. I was looking at `erc-channel-user-owner' not the predicate form `erc-channel-user-owner-p'. > > + 2014-06-11 Kelvin White <kelvin.white77@gmail.com> > > + > > + * erc-backend.el: Handle user modes in relevent server responses > > + * erc.el: Better user mode support. > > + (erc-channel-user): Add members for new modes. > > + (erc-channel-member-halfop-p, erc-channel-user-admin-p, erc-channel-user-owner-p): Use new struct members. > > + (erc-format-nick, erc-format-@nick): Display user modes as nick prefix. > > + (erc-nick-prefix-face, erc-my-nick-prefix-face): Add new faces to separate colors if desired. > > + (erc-get-user-mode-prefix): Return symbol for mode prefix. > > + (erc-update-channel-member, erc-update-current-channel-member, erc-channel-receive-names): Update channel users. > > + (erc-nick-at-point): Return correct user info. > > + > Ah yes, I did change the rest of the code to under 80 columns, but it looks like I missed the changelog. Sorry, it's been one of those days. > Please try a bit harder to stay within 80 columns. M-q is your friend. > > > ! ;; Hacker: l3thal@smashthestack.org > > ! ;; Created: 2004-05-07 > > ! ;; Hacked: 2014-06-08 > This and the next comment slipped my me on mistake. This was for my own use to track revisions as It wasn't in version control. It should not have been included in the patch > If you want to add your name, add it to the "Author:" part (one per > line, see in erc.el for an example). And don't add entries like > timestamps of when it was last changed. This just causes spurious > conflicts when merging branches. This info is readily available via > "bzr log". I tolerate things like "Created" (tho find it a waste of > perfectly good bits and screen real estate) because, by nature these > should never change and hence don't cause such spurious conflicts. > > > ! ;;; hacked > > (define-erc-response-handler (JOIN) > > ! "HACKED: Handle join messages." > > What does this "hacked" mean here? Looks like left-over annotations you > used temporarily to keep track of what you changed. This was a mistake, please see above. > > Anyway, the patch looks OK to me. As soon as your copyright paperwork > comes through I can give you write access and you can install it. > > > Stefan ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#17755: 24.3; ERC user mode support 2014-06-11 10:34 bug#17755: 24.3; ERC user mode support kelvin.white77 2014-06-11 11:45 ` Kelvin White @ 2014-10-02 19:31 ` Paul Eggert 1 sibling, 0 replies; 8+ messages in thread From: Paul Eggert @ 2014-10-02 19:31 UTC (permalink / raw) To: Kelvin White; +Cc: 17755 [-- Attachment #1: Type: text/plain, Size: 109 bytes --] I found a typo in that patch and installed the attached further minor patch to fix it, as trunk bzr 118017. [-- Attachment #2: erc.diff --] [-- Type: text/x-patch, Size: 938 bytes --] === modified file 'lisp/erc/ChangeLog' --- lisp/erc/ChangeLog 2014-10-02 11:55:22 +0000 +++ lisp/erc/ChangeLog 2014-10-02 19:27:33 +0000 @@ -1,3 +1,7 @@ +2014-10-02 Paul Eggert <eggert@cs.ucla.edu> + + * erc.el (erc-nick-at-point): Fix format-string typo (Bug#17755). + 2014-10-02 Kelvin White <kwhite@gnu.org> * erc.el (erc-rename-buffer-p): When set to t buffers will be === modified file 'lisp/erc/erc.el' --- lisp/erc/erc.el 2014-10-02 11:55:22 +0000 +++ lisp/erc/erc.el 2014-10-02 19:27:04 +0000 @@ -6082,7 +6082,7 @@ nick login host (if full-name (format " (%s)" full-name) "") (if (or voice halfop op admin owner) - (format " and is +%s%s on %s" + (format " and is +%s%s%s%s%s on %s" (if voice "v" "") (if halfop "h" "") (if op "o" "") ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-10-02 19:31 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-06-11 10:34 bug#17755: 24.3; ERC user mode support kelvin.white77 2014-06-11 11:45 ` Kelvin White 2014-06-17 16:03 ` Stefan Monnier 2014-06-18 14:40 ` Kelvin White 2014-06-18 16:08 ` Kelvin White 2014-06-18 18:32 ` Stefan Monnier 2014-06-18 18:51 ` Kelvin White 2014-10-02 19:31 ` Paul Eggert
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).