diff options
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/net/rcirc.el | 296 |
2 files changed, 182 insertions, 122 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f6e01b030a1..7eb0a8336b7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -4,6 +4,14 @@ | |||
| 4 | process is open, since not all commands need an open process. | 4 | process is open, since not all commands need an open process. |
| 5 | (rcirc-send-string): Check whether the process is open before | 5 | (rcirc-send-string): Check whether the process is open before |
| 6 | sending anything. | 6 | sending anything. |
| 7 | (rcirc-ignore-list): New option. | ||
| 8 | (rcirc-ignore-list-automatic): New variable. | ||
| 9 | (rcirc-print): Take rcirc-ignore-list into account. | ||
| 10 | (rcirc-cmd-ignore): New command. | ||
| 11 | (rcirc-ignore-update-automatic): New function. | ||
| 12 | (rcirc-handler-PART, rcirc-handler-QUIT): Use it to maintain the | ||
| 13 | list if ignored nicks. | ||
| 14 | (rcirc-handler-NICK): Ditto, and also ignore the new nick. | ||
| 7 | 15 | ||
| 8 | 2006-01-06 David Reitter <david.reitter@gmail.com> | 16 | 2006-01-06 David Reitter <david.reitter@gmail.com> |
| 9 | 17 | ||
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index ed507860dc7..ca007554267 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el | |||
| @@ -181,6 +181,18 @@ use either M-x customize or also call `rcirc-update-prompt'." | |||
| 181 | :initialize 'custom-initialize-default | 181 | :initialize 'custom-initialize-default |
| 182 | :group 'rcirc) | 182 | :group 'rcirc) |
| 183 | 183 | ||
| 184 | (defcustom rcirc-ignore-list () | ||
| 185 | "List of ignored nicks. | ||
| 186 | Use /ignore to list them, use /ignore NICK to add or remove a nick." | ||
| 187 | :type '(repeat string) | ||
| 188 | :group 'rcirc) | ||
| 189 | |||
| 190 | (defvar rcirc-ignore-list-automatic () | ||
| 191 | "List of ignored nicks added to `rcirc-ignore-list' because of renaming. | ||
| 192 | When an ignored person renames, their nick is added to both lists. | ||
| 193 | Nicks will be removed from the automatic list on follow-up renamings or | ||
| 194 | parts.") | ||
| 195 | |||
| 184 | (defcustom rcirc-print-hooks nil | 196 | (defcustom rcirc-print-hooks nil |
| 185 | "Hook run after text is printed. | 197 | "Hook run after text is printed. |
| 186 | Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT." | 198 | Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT." |
| @@ -192,6 +204,14 @@ Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT." | |||
| 192 | 204 | ||
| 193 | (defvar rcirc-nick-table nil) | 205 | (defvar rcirc-nick-table nil) |
| 194 | 206 | ||
| 207 | (defvar rcirc-nick-syntax-table | ||
| 208 | (let ((table (make-syntax-table text-mode-syntax-table))) | ||
| 209 | (mapc (lambda (c) (modify-syntax-entry c "w" table)) | ||
| 210 | "[]\\`_^{|}-") | ||
| 211 | (modify-syntax-entry ?' "_" table) | ||
| 212 | table) | ||
| 213 | "Syntax table which includes all nick characters as word constituents.") | ||
| 214 | |||
| 195 | ;; each process has an alist of (target . buffer) pairs | 215 | ;; each process has an alist of (target . buffer) pairs |
| 196 | (defvar rcirc-buffer-alist nil) | 216 | (defvar rcirc-buffer-alist nil) |
| 197 | 217 | ||
| @@ -906,120 +926,124 @@ Create the buffer if it doesn't exist." | |||
| 906 | "Print TEXT in the buffer associated with TARGET. | 926 | "Print TEXT in the buffer associated with TARGET. |
| 907 | Format based on SENDER and RESPONSE. If ACTIVITY is non-nil, | 927 | Format based on SENDER and RESPONSE. If ACTIVITY is non-nil, |
| 908 | record activity." | 928 | record activity." |
| 909 | (let* ((buffer (cond ((bufferp target) | 929 | (unless (or (member (rcirc-user-nick sender) rcirc-ignore-list) |
| 910 | target) | 930 | (member (with-syntax-table rcirc-nick-syntax-table |
| 911 | ((not target) | 931 | (when (string-match "^\\([^/]\\w*\\)[:,]" text) |
| 912 | (rcirc-get-any-buffer process)) | 932 | (match-string 1 text))) rcirc-ignore-list)) |
| 913 | ((not (rcirc-channel-p target)) | 933 | (let* ((buffer (cond ((bufferp target) |
| 914 | (rcirc-get-buffer-create process | 934 | target) |
| 915 | (rcirc-user-nick sender))) | 935 | ((not target) |
| 916 | ((or (rcirc-get-buffer process target) | 936 | (rcirc-get-any-buffer process)) |
| 917 | (rcirc-get-any-buffer process))))) | 937 | ((not (rcirc-channel-p target)) |
| 918 | (inhibit-read-only t)) | 938 | (rcirc-get-buffer-create process |
| 919 | (with-current-buffer buffer | 939 | (rcirc-user-nick sender))) |
| 920 | (let ((moving (= (point) rcirc-prompt-end-marker)) | 940 | ((or (rcirc-get-buffer process target) |
| 921 | (old-point (point-marker)) | 941 | (rcirc-get-any-buffer process))))) |
| 922 | (fill-start (marker-position rcirc-prompt-start-marker))) | 942 | (inhibit-read-only t)) |
| 923 | 943 | (with-current-buffer buffer | |
| 924 | (unless (string= sender (rcirc-nick process)) | 944 | (let ((moving (= (point) rcirc-prompt-end-marker)) |
| 925 | ;; only decode text from other senders, not ours | 945 | (old-point (point-marker)) |
| 926 | (setq text (decode-coding-string (or text "") | 946 | (fill-start (marker-position rcirc-prompt-start-marker))) |
| 927 | buffer-file-coding-system)) | 947 | |
| 928 | ;; mark the line with overlay arrow | 948 | (unless (string= sender (rcirc-nick process)) |
| 929 | (unless (or (marker-position overlay-arrow-position) | 949 | ;; only decode text from other senders, not ours |
| 930 | (get-buffer-window (current-buffer))) | 950 | (setq text (decode-coding-string (or text "") |
| 931 | (set-marker overlay-arrow-position | 951 | buffer-file-coding-system)) |
| 932 | (marker-position rcirc-prompt-start-marker)))) | 952 | ;; mark the line with overlay arrow |
| 933 | 953 | (unless (or (marker-position overlay-arrow-position) | |
| 934 | ;; temporarily set the marker insertion-type because | 954 | (get-buffer-window (current-buffer))) |
| 935 | ;; insert-before-markers results in hidden text in new buffers | 955 | (set-marker overlay-arrow-position |
| 936 | (goto-char rcirc-prompt-start-marker) | 956 | (marker-position rcirc-prompt-start-marker)))) |
| 937 | (set-marker-insertion-type rcirc-prompt-start-marker t) | 957 | |
| 938 | (set-marker-insertion-type rcirc-prompt-end-marker t) | 958 | ;; temporarily set the marker insertion-type because |
| 939 | (insert | 959 | ;; insert-before-markers results in hidden text in new buffers |
| 940 | (rcirc-format-response-string process sender response target text) | 960 | (goto-char rcirc-prompt-start-marker) |
| 941 | (propertize "\n" 'hard t)) | 961 | (set-marker-insertion-type rcirc-prompt-start-marker t) |
| 942 | (set-marker-insertion-type rcirc-prompt-start-marker nil) | 962 | (set-marker-insertion-type rcirc-prompt-end-marker t) |
| 943 | (set-marker-insertion-type rcirc-prompt-end-marker nil) | 963 | (insert |
| 944 | 964 | (rcirc-format-response-string process sender response target text) | |
| 945 | ;; fill the text we just inserted, maybe | 965 | (propertize "\n" 'hard t)) |
| 946 | (when (and rcirc-fill-flag | 966 | (set-marker-insertion-type rcirc-prompt-start-marker nil) |
| 947 | (not (string= response "372"))) ;/motd | 967 | (set-marker-insertion-type rcirc-prompt-end-marker nil) |
| 948 | (let ((fill-prefix | 968 | |
| 949 | (or rcirc-fill-prefix | 969 | ;; fill the text we just inserted, maybe |
| 950 | (make-string | 970 | (when (and rcirc-fill-flag |
| 951 | (+ (if rcirc-time-format | 971 | (not (string= response "372"))) ;/motd |
| 952 | (length (format-time-string | 972 | (let ((fill-prefix |
| 953 | rcirc-time-format)) | 973 | (or rcirc-fill-prefix |
| 954 | 0) | 974 | (make-string |
| 955 | (cond ((or (string= response "PRIVMSG") | 975 | (+ (if rcirc-time-format |
| 956 | (string= response "NOTICE")) | 976 | (length (format-time-string |
| 957 | (+ (length (rcirc-user-nick sender)) | 977 | rcirc-time-format)) |
| 958 | 2)) ; <> | 978 | 0) |
| 959 | ((string= response "ACTION") | 979 | (cond ((or (string= response "PRIVMSG") |
| 960 | (+ (length (rcirc-user-nick sender)) | 980 | (string= response "NOTICE")) |
| 961 | 1)) ; [ | 981 | (+ (length (rcirc-user-nick sender)) |
| 962 | (t 3)) ; *** | 982 | 2)) ; <> |
| 963 | 1) | 983 | ((string= response "ACTION") |
| 964 | ? ))) | 984 | (+ (length (rcirc-user-nick sender)) |
| 965 | (fill-column (cond ((eq rcirc-fill-column 'frame-width) | 985 | 1)) ; [ |
| 966 | (1- (frame-width))) | 986 | (t 3)) ; *** |
| 967 | (rcirc-fill-column | 987 | 1) |
| 968 | rcirc-fill-column) | 988 | ? ))) |
| 969 | (t fill-column)))) | 989 | (fill-column (cond ((eq rcirc-fill-column 'frame-width) |
| 970 | (fill-region fill-start rcirc-prompt-start-marker 'left t))) | 990 | (1- (frame-width))) |
| 971 | 991 | (rcirc-fill-column | |
| 972 | ;; set inserted text to be read-only | 992 | rcirc-fill-column) |
| 973 | (when rcirc-read-only-flag | 993 | (t fill-column)))) |
| 974 | (put-text-property rcirc-prompt-start-marker fill-start 'read-only t) | 994 | (fill-region fill-start rcirc-prompt-start-marker 'left t))) |
| 975 | (let ((inhibit-read-only t)) | 995 | |
| 976 | (put-text-property rcirc-prompt-start-marker fill-start | 996 | ;; set inserted text to be read-only |
| 977 | 'front-sticky t) | 997 | (when rcirc-read-only-flag |
| 978 | (put-text-property (1- (point)) (point) 'rear-nonsticky t))) | 998 | (put-text-property rcirc-prompt-start-marker fill-start 'read-only t) |
| 979 | 999 | (let ((inhibit-read-only t)) | |
| 980 | ;; truncate buffer if it is very long | 1000 | (put-text-property rcirc-prompt-start-marker fill-start |
| 981 | (save-excursion | 1001 | 'front-sticky t) |
| 982 | (when (and rcirc-buffer-maximum-lines | 1002 | (put-text-property (1- (point)) (point) 'rear-nonsticky t))) |
| 983 | (> rcirc-buffer-maximum-lines 0) | 1003 | |
| 984 | (= (forward-line (- rcirc-buffer-maximum-lines)) 0)) | 1004 | ;; truncate buffer if it is very long |
| 985 | (delete-region (point-min) (point)))) | 1005 | (save-excursion |
| 986 | 1006 | (when (and rcirc-buffer-maximum-lines | |
| 987 | ;; set the window point for buffers show in windows | 1007 | (> rcirc-buffer-maximum-lines 0) |
| 988 | (walk-windows (lambda (w) | 1008 | (= (forward-line (- rcirc-buffer-maximum-lines)) 0)) |
| 989 | (unless (eq (selected-window) w) | 1009 | (delete-region (point-min) (point)))) |
| 990 | (when (and (eq (current-buffer) | 1010 | |
| 991 | (window-buffer w)) | 1011 | ;; set the window point for buffers show in windows |
| 992 | (>= (window-point w) | 1012 | (walk-windows (lambda (w) |
| 993 | rcirc-prompt-end-marker)) | 1013 | (unless (eq (selected-window) w) |
| 994 | (set-window-point w (point-max))))) | 1014 | (when (and (eq (current-buffer) |
| 995 | nil t) | 1015 | (window-buffer w)) |
| 996 | 1016 | (>= (window-point w) | |
| 997 | ;; restore the point | 1017 | rcirc-prompt-end-marker)) |
| 998 | (goto-char (if moving rcirc-prompt-end-marker old-point)) | 1018 | (set-window-point w (point-max))))) |
| 999 | 1019 | nil t) | |
| 1000 | ;; flush undo (can we do something smarter here?) | 1020 | |
| 1001 | (buffer-disable-undo) | 1021 | ;; restore the point |
| 1002 | (buffer-enable-undo)) | 1022 | (goto-char (if moving rcirc-prompt-end-marker old-point)) |
| 1003 | 1023 | ||
| 1004 | ;; record modeline activity | 1024 | ;; flush undo (can we do something smarter here?) |
| 1005 | (when activity | 1025 | (buffer-disable-undo) |
| 1006 | (let ((nick-match | 1026 | (buffer-enable-undo)) |
| 1007 | (string-match (concat "\\b" | 1027 | |
| 1008 | (regexp-quote (rcirc-nick process)) | 1028 | ;; record modeline activity |
| 1009 | "\\b") | 1029 | (when activity |
| 1010 | text))) | 1030 | (let ((nick-match |
| 1011 | (when (or (not rcirc-ignore-buffer-activity-flag) | 1031 | (string-match (concat "\\b" |
| 1012 | ;; always notice when our nick is mentioned, even | 1032 | (regexp-quote (rcirc-nick process)) |
| 1013 | ;; if ignoring channel activity | 1033 | "\\b") |
| 1014 | nick-match) | 1034 | text))) |
| 1015 | (rcirc-record-activity | 1035 | (when (or (not rcirc-ignore-buffer-activity-flag) |
| 1016 | (current-buffer) | 1036 | ;; always notice when our nick is mentioned, even |
| 1017 | (when (or nick-match (not (rcirc-channel-p rcirc-target))) | 1037 | ;; if ignoring channel activity |
| 1018 | 'nick))))) | 1038 | nick-match) |
| 1019 | 1039 | (rcirc-record-activity | |
| 1020 | (sit-for 0) ; displayed text before hook | 1040 | (current-buffer) |
| 1021 | (run-hook-with-args 'rcirc-print-hooks | 1041 | (when (or nick-match (not (rcirc-channel-p rcirc-target))) |
| 1022 | process sender response target text)))) | 1042 | 'nick))))) |
| 1043 | |||
| 1044 | (sit-for 0) ; displayed text before hook | ||
| 1045 | (run-hook-with-args 'rcirc-print-hooks | ||
| 1046 | process sender response target text))))) | ||
| 1023 | 1047 | ||
| 1024 | (defun rcirc-startup-channels (server) | 1048 | (defun rcirc-startup-channels (server) |
| 1025 | "Return the list of startup channels for server." | 1049 | "Return the list of startup channels for server." |
| @@ -1101,6 +1125,15 @@ record activity." | |||
| 1101 | rcirc-nick-table) | 1125 | rcirc-nick-table) |
| 1102 | (mapcar (lambda (x) (car x)) | 1126 | (mapcar (lambda (x) (car x)) |
| 1103 | (sort nicks (lambda (x y) (time-less-p (cdr y) (cdr x)))))))) | 1127 | (sort nicks (lambda (x y) (time-less-p (cdr y) (cdr x)))))))) |
| 1128 | |||
| 1129 | (defun rcirc-ignore-update-automatic (nick) | ||
| 1130 | "Remove NICK from `rcirc-ignore-list' | ||
| 1131 | if NICK is also on `rcirc-ignore-list-automatic'." | ||
| 1132 | (when (member nick rcirc-ignore-list-automatic) | ||
| 1133 | (setq rcirc-ignore-list-automatic | ||
| 1134 | (delete nick rcirc-ignore-list-automatic) | ||
| 1135 | rcirc-ignore-list | ||
| 1136 | (delete nick rcirc-ignore-list)))) | ||
| 1104 | 1137 | ||
| 1105 | ;;; activity tracking | 1138 | ;;; activity tracking |
| 1106 | (or (assq 'rcirc-ignore-buffer-activity-flag minor-mode-alist) | 1139 | (or (assq 'rcirc-ignore-buffer-activity-flag minor-mode-alist) |
| @@ -1448,6 +1481,26 @@ With a prefix arg, prompt for new topic." | |||
| 1448 | (defun rcirc-cmd-me (args &optional process target) | 1481 | (defun rcirc-cmd-me (args &optional process target) |
| 1449 | (rcirc-send-string process (format "PRIVMSG %s :\C-aACTION %s\C-a" | 1482 | (rcirc-send-string process (format "PRIVMSG %s :\C-aACTION %s\C-a" |
| 1450 | target args))) | 1483 | target args))) |
| 1484 | |||
| 1485 | (defun-rcirc-command ignore (nick) | ||
| 1486 | "Manage the ignore list. | ||
| 1487 | Ignore NICK, unignore NICK if already ignored, or list ignored | ||
| 1488 | nicks when no NICK is given. When listing ignored nicks, the | ||
| 1489 | ones added to the list automatically are marked with an asterix." | ||
| 1490 | (interactive "sToggle ignoring of nick: ") | ||
| 1491 | (if (string= "" nick) | ||
| 1492 | (rcirc-print process (rcirc-nick process) "NOTICE" target | ||
| 1493 | (mapconcat | ||
| 1494 | (lambda (nick) | ||
| 1495 | (concat nick | ||
| 1496 | (if (member nick rcirc-ignore-list-automatic) | ||
| 1497 | "*" ""))) | ||
| 1498 | rcirc-ignore-list " ")) | ||
| 1499 | (if (member nick rcirc-ignore-list) | ||
| 1500 | (setq rcirc-ignore-list (delete nick rcirc-ignore-list)) | ||
| 1501 | (setq rcirc-ignore-list (cons nick rcirc-ignore-list))))) | ||
| 1502 | |||
| 1503 | |||
| 1451 | 1504 | ||
| 1452 | (defun rcirc-message-leader (sender face) | 1505 | (defun rcirc-message-leader (sender face) |
| 1453 | "Return a string with SENDER propertized with FACE." | 1506 | "Return a string with SENDER propertized with FACE." |
| @@ -1502,14 +1555,6 @@ FUNCTION takes 3 arguments, MATCH-START, MATCH-END, and STRING." | |||
| 1502 | (funcall function (match-beginning 0) (match-end 0) string))) | 1555 | (funcall function (match-beginning 0) (match-end 0) string))) |
| 1503 | string) | 1556 | string) |
| 1504 | 1557 | ||
| 1505 | (defvar rcirc-nick-syntax-table | ||
| 1506 | (let ((table (make-syntax-table text-mode-syntax-table))) | ||
| 1507 | (mapc (lambda (c) (modify-syntax-entry c "w" table)) | ||
| 1508 | "[]\\`_^{|}-") | ||
| 1509 | (modify-syntax-entry ?' "_" table) | ||
| 1510 | table) | ||
| 1511 | "Syntax table which includes all nick characters as word constituents.") | ||
| 1512 | |||
| 1513 | (defun rcirc-mangle-text (process text) | 1558 | (defun rcirc-mangle-text (process text) |
| 1514 | "Return TEXT with properties added based on various patterns." | 1559 | "Return TEXT with properties added based on various patterns." |
| 1515 | ;; ^B | 1560 | ;; ^B |
| @@ -1650,6 +1695,7 @@ FUNCTION takes 3 arguments, MATCH-START, MATCH-END, and STRING." | |||
| 1650 | (setq rcirc-target nil)))))) | 1695 | (setq rcirc-target nil)))))) |
| 1651 | 1696 | ||
| 1652 | (defun rcirc-handler-PART (process sender args text) | 1697 | (defun rcirc-handler-PART (process sender args text) |
| 1698 | (rcirc-ignore-update-automatic (rcirc-user-nick sender)) | ||
| 1653 | (rcirc-handler-PART-or-KICK process "PART" | 1699 | (rcirc-handler-PART-or-KICK process "PART" |
| 1654 | (car args) sender (rcirc-user-nick sender) | 1700 | (car args) sender (rcirc-user-nick sender) |
| 1655 | (cadr args))) | 1701 | (cadr args))) |
| @@ -1659,6 +1705,7 @@ FUNCTION takes 3 arguments, MATCH-START, MATCH-END, and STRING." | |||
| 1659 | (caddr args))) | 1705 | (caddr args))) |
| 1660 | 1706 | ||
| 1661 | (defun rcirc-handler-QUIT (process sender args text) | 1707 | (defun rcirc-handler-QUIT (process sender args text) |
| 1708 | (rcirc-ignore-update-automatic (rcirc-user-nick sender)) | ||
| 1662 | (let ((nick (rcirc-user-nick sender))) | 1709 | (let ((nick (rcirc-user-nick sender))) |
| 1663 | (mapc (lambda (channel) | 1710 | (mapc (lambda (channel) |
| 1664 | (rcirc-print process sender "QUIT" channel (apply 'concat args))) | 1711 | (rcirc-print process sender "QUIT" channel (apply 'concat args))) |
| @@ -1675,6 +1722,11 @@ FUNCTION takes 3 arguments, MATCH-START, MATCH-END, and STRING." | |||
| 1675 | (let* ((old-nick (rcirc-user-nick sender)) | 1722 | (let* ((old-nick (rcirc-user-nick sender)) |
| 1676 | (new-nick (car args)) | 1723 | (new-nick (car args)) |
| 1677 | (channels (rcirc-nick-channels process old-nick))) | 1724 | (channels (rcirc-nick-channels process old-nick))) |
| 1725 | ;; update list of ignored nicks | ||
| 1726 | (rcirc-ignore-update-automatic old-nick) | ||
| 1727 | (when (member old-nick rcirc-ignore-list) | ||
| 1728 | (add-to-list 'rcirc-ignore-list new-nick) | ||
| 1729 | (add-to-list 'rcirc-ignore-list-automatic new-nick)) | ||
| 1678 | ;; print message to nick's channels | 1730 | ;; print message to nick's channels |
| 1679 | (dolist (target channels) | 1731 | (dolist (target channels) |
| 1680 | (rcirc-print process sender "NICK" target new-nick)) | 1732 | (rcirc-print process sender "NICK" target new-nick)) |