;;; ********************************************************************** ;;; Almost complete ERC (Emacs IRC client) configuration of Richard ;;; Klinda ;;; I usually hang out on #emacs@freenode with the nick 'ignotus'. ;;; Last modified: Thursday, May 29, 2003 ;;; URL: http://ignotus.linuxforum.hu/erc-init.el ;;; I use this configuration with ERC CVS 2003-04-08 and XEmacs 21. ;;; ---------------------------------------------------------------------- ;;; ############################################################# `ERC ### ;;; ---------------------------------------------------------------------- (require 'erc) (require 'erc-fill) (require 'erc-match) (require 'erc-complete) ;;; "#trivia" ;;; ;"#finance" ;;; ;"#giFT" ;;; "#zsh" ;;; ;"#awk" ;;; ;"#mldonkey" ;;; "#sawfish" ;;; "#emacs" ;;; ;"#xwin" ;;; "#XFree86" ;;; "#lisp" ;;; ;"#mplayer" ;;; ;"#kernelnewbies" ;;; ;"#wopn" ;;; ;"#debian-devel" ;;; )) ;;; ;; from: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcStartupFiles ;;; (defun myerc-join-channels (&rest channels) ;;; (mapc 'erc-join-channel channels)) ;;; ;;; .............................................................. ICQ ... ;;; ;; bitlbee icq stuff ;;; (defun icq () ;;; (interactive) ;;; (call-process "random-nick") ;;; (setq erc-user-full-name ;;; (concat (ign-randomize-nick-2 (copy-sequence "ignotus") 12) ;;; (ign-randomize-nick-2 (copy-sequence " maximus") 55))) ;;; (erc-select "localhost" "6676" "ignotus")) ;;; ;; #bitlbee onjoin trigger ;;; (defun bitlbee-identify (proc parsed) ;;; (let* ((cmd (aref parsed 0)) ;;; (tgt (aref parsed 2)) ;;; (msg (aref parsed 3))) ;;; (when (equalp msg "#bitlbee") ;;; (insert "identify " bittlbe-password)))) ;;; (add-hook 'erc-server-366-hook 'bitlbee-identify) ;;; ;;; .................................................... misc settings ... ;;; (setq erc-server-history-list '("irc.freenode.net" ;;; "irc.oftc.net" ;;; "irc.elte.hu" ;;; "irc.trefort.net" ;;; "wikked.irchat.tv")) ;;; (setq erc-fill-column 65 ;;; erc-flood-protect nil) ;;; ;;; .......................................... erc-track-switch-buffer ... ;;; ;; this functon is a wrapper to SWITCH-TO-BUFFER, but it switches ;;; ;; sawfish viewport if the target buffer is visible on another emacs ;;; ;; frame (which is on another viewport) (i usually have 3-8 emacs ;;; ;; frames scattered thru my 16 viewports) ;;; (defun ign-switch-to-frame-and-buffer (buffer) ;;; (let* ((frame (and (get-buffer-window buffer t) ;;; (get-frame-for-buffer buffer))) ;;; (id (and frame ;;; (member (frame-visible-p frame) '(hidden)) ;;; (format "%x" (- (string-to-number ;;; (frame-property frame 'window-id)) ;;; 3))))) ;;; (if id ;;; ;; switch viewport ;;; (start-process "yay" nil "/usr/bin/sawfish-client" "-e" ;;; (format ;;; "(move-viewport-to-window (get-window-by-id 0x%s))" ;;; id)) ;;; ;; switch to buffer ;;; (switch-to-buffer buffer)))) ;;; ;; enhanced ERC-TRACK-SWITCH-BUFFER ;;; (defun erc-track-switch-buffer (arg) ;;; "Switch to the next active ERC buffer, or if there are no active buffers, ;;; switch back to the last non-ERC buffer visited. Next is defined by ;;; `erc-track-switch-direction', a negative argument will reverse this." ;;; (interactive "p") ;;; (when erc-track-mode ;;; (let ((dir erc-track-switch-direction)) ;;; (if erc-modified-channels-alist ;;; (progn ;;; ;; if we're not in erc-mode, set this buffer to return to ;;; (unless (eq major-mode 'erc-mode) ;;; (setq erc-track-last-non-erc-buffer (current-buffer))) ;;; ;; and jump to the next active channel ;;; (let ((b (erc-track-get-active-buffer arg))) ;;; (ign-switch-to-frame-and-buffer b) ;<-igno ;;; ; (switch-to-buffer b) ;;; (setf erc-modified-channels-alist ;<- igno ;;; (remove* b erc-modified-channels-alist ;;; :key 'car)) ;;; (erc-modified-channels-display))) ;;; ;; if no active channels, switch back to what we were doing before ;;; (when (and erc-track-last-non-erc-buffer ;;; erc-track-switch-from-erc ;;; (buffer-live-p erc-track-last-non-erc-buffer)) ;;; (ign-switch-to-frame-and-buffer ;<- igno ;;; erc-track-last-non-erc-buffer)))))) ;;; ;;; ...................................................................... ;;; ;;; smart fill ;;; ;; Instant messaging services like IRC are crowded with "one line ;;; ;; wonders", you know, people who can't resist hitting enter after every ;;; ;; single word they write. Smart-fill rewrites text like this: ;;; ;; hey ;;; ;; ignotus !! ;;; ;; how ;;; ;; are u ;;; ;; man ;;; ;; are you ;;; ;; here???? ;;; ;; ignotus!! ;;; ;; into a more eye pleasing: ;;; ;; hey ## ignotus !! ## how ## are u ## man ## are you ;;; ;; ## here???? ## ignotus!! ;;; ;; these nicks ;;; (defvar ign-erc-smart-fill-ignore '("Mojojojo" "sarti" "fsbot")) ;;; (defvar ign-erc-smart-fill-p t) ;;; ;; ERC separator should have a bright color on it ;;; (defvar ign-erc-separator " ## ") ;;; (add-text-properties 0 4 '(face erc-input-face) ign-erc-separator) ;;; (defvar ign-erc-last-nick nil) ;;; (defun ign-erc-smart-fill (string) ;;; (unless ign-erc-last-nick ;;; (make-variable-buffer-local 'ign-erc-last-nick) ;;; (setq ign-erc-last-nick t)) ;;; (when ign-erc-smart-fill-p ;;; (save-excursion ;;; (if (string-match "^<\\(.*?\\)> \\(.*\\)" string) ;;; (let ((nick (match-string 1 string)) ;;; (text (match-string 2 string))) ;;; (if (and (equalp nick ign-erc-last-nick) ;;; (not (member nick ign-erc-smart-fill-ignore))) ;;; (progn ; we have work ;;; (goto-char (point-max)) ;;; (erc-bol) ;;; (if (and (re-search-backward (concat "^ *<\\(.*?\\)>") nil t) ;;; (equalp (match-string 1) nick)) ;;; ;;search for the end of users previous text ;;; (let ((beg (match-beginning 0))) ;;; (beginning-of-line) ;;; (tinyeat-backward-preserve) ;;; (end-of-line) ;;; (while (re-search-forward "^ .*" nil t) ;;; (goto-char (match-end 0))) ;;; (insert ign-erc-separator text "\n") ;;; (save-restriction ;;; (narrow-to-region beg (point)) ;;; ;; fill static ;;; (erc-fill-static) ;;; (goto-char (point-max)) ;;; (delete-backward-char 1) ;;; ;; erc match ;;; (erc-match-message) ;;; ;; X-Face-t beszurok ;;; (goto-char (point-min)) ;;; (ign-insert-irc-face)) ;;; ;;oksa ezt nem kell kiirni ;;; (setq erc-insert-this nil) ;;; nil) ;;; ;; if don't find it then do just display ;;; nil)) ;;; (progn ;;; (setq ign-erc-last-nick nick) ;;; nil))) ;;; ;; just display ;;; (progn ;;; (setq ign-erc-last-nick t) ;;; nil))))) ;;; (add-hook 'erc-insert-pre-hook 'ign-erc-smart-fill) ;;; ;;; ...................................................................... ;;; ;; PRIVMSG ignore ;;; ;; I don't accept private messages by default (it's a must if you hang ;;; ;; out on support channels). ;;; ;; Put nicks here you want to allow. You can use '/allow nick' inside ;;; ;; erc, but those changes aren't saved. ;;; (defvar ign-erc-privmsg-allow ;;; '("al3x" "alex" "trey" "danko" "stevee" "veszig" "vili" "friczy" ;;; "drewie")) ;;; (defvar ign-erc-privmsg-ignore-last-notice nil) ;;; (defun erc-cmd-ALLOW (line &optional force) ;;; (if (string-match "\\S +" line) ;;; (let ((new-allow (match-string 0 line))) ;;; (erc-display-line ;;; (erc-make-notice (format "Now allowing %s" new-allow)) ;;; 'active) ;;; (add-to-list 'ign-erc-privmsg-allow new-allow)) ;;; (erc-display-line ;;; (erc-make-notice (format "Allow list: %s" ign-erc-privmsg-allow)) ;;; 'active))) ;;; (defun ign-erc-privmsg-hook-ignore (proc parsed) ;;; (let* ((cmd (aref parsed 0)) ;;; (sspec (aref parsed 1)) ;;; (tgt (aref parsed 2)) ;;; (msg (aref parsed 3)) ;;; (sender (erc-parse-user sspec)) ;;; (nick (nth 0 sender))) ;;; ;; ignore? ;;; (when (and (string-equal tgt erc-nick) ;;; (not (member nick ign-erc-privmsg-allow))) ;;; ;; send warning back? maximum 1 warning per 8 seconds ;;; (when (or (not ign-erc-privmsg-ignore-last-notice) ;;; (< ign-erc-privmsg-ignore-last-notice ;;; (- (erc-current-time) 8))) ;;; (erc-send-ctcp-notice nick "Sorry, private messages are ignored automatically. HUN: Privatban csak akkor ha TENYLEG PRIVAT, amugy mindent latok ami a csatin megy ha ele irod a nickemet: \"ignotus: blahblah\" <- kliensem kigyujti, szinezi, ledjeim villognak tole, kulonbozo beep hangok, email notification, automatikusan todolist-be kerul stb! Tehat csatin...") ;;; (setq ign-erc-privmsg-ignore-last-notice (erc-current-time))) ;;; t))) ;;; (add-hook 'erc-server-PRIVMSG-hook 'ign-erc-privmsg-hook-ignore) ;;; ;;; ...................................................................... ;;; ;; Ignore joins, parts and quits in current channel. ;;; ;; conference mode ;;; (setq erc-conference-p nil) ;;; (defun erc-cmd-CONFERENCE (&optional force) ;;; (if (and (boundp 'erc-conference-p) ;;; erc-conference-p) ;;; (progn ;;; (setq erc-conference-p nil ;;; erc-hide-list (default-value erc-hide-list)) ;;; (erc-display-line (erc-make-notice "Conference mode is OFF.") ;;; 'active)) ;;; (progn ;;; (make-local-variable 'erc-hide-list) ;;; (make-local-variable 'erc-conference-p) ;;; (setq erc-conference-p t ;;; erc-hide-list '("JOIN" "PART" "QUIT")) ;;; (erc-display-line (erc-make-notice "Conference mode is ON.") ;;; 'active))) ;;; t) ;;; ;;; ...................................................................... ;;; ;; signal on personal message ;;; ;; When someone mentions my name on a channel I get a nice animation on ;;; ;; my keyboard leds and/or sounds. ;;; (defvar *ign-erc-beep-p* t) ;;; (defvar *ign-erc-privmsg-beep-last-time* 0) ;;; (defun ign-erc-privmsg-hook-beeper (proc parsed) ;;; (let* ((cmd (aref parsed 0)) ;;; (tgt (aref parsed 2)) ;;; (msg (aref parsed 3))) ;;; (when (and (not (string= cmd "NOTICE")) ;;; (or ;(equalp tgt (erc-current-nick)) ;;; (string-match (erc-current-nick) msg))) ;;; ;; maximum 1 triggering in 3 seconds ;;; (if (> (- (erc-current-time) *ign-erc-privmsg-beep-last-time*) 3) ;;; (when *ign-erc-beep-p* ;;; (setq ign-erc-privmsg-beep-last-time (erc-current-time)) ;;; ;(start-process "erc-beep" nil "bplay" ;;; ; "/home/ignotus/.beeps/clink.wav") ;;; (start-process "erc-ledcontrol" nil "sudo" ;;; "ledcontrol" "anim S 200 C 200 N 200 s 200 c 200 n")) ;;; (setq ign-erc-privmsg-beep-last-time (erc-current-time)))) ;;; nil)) ;;; (add-hook 'erc-server-PRIVMSG-hook 'ign-erc-privmsg-hook-beeper) ;;; ;;; ...................................................................... ;;; ;; stock player ;;; ;; #finance@freenode is a stock market simulation game for the really ;;; ;; bored, this is a very primitive bot-player for it, well, it ;;; ;; sucks. :-) ;;; (defvar *stock-ai* '(("LNUX" 0.94 buy) ;;; ("LNUX" 1.95 sell) ;;; ;("SGI" 1.35 buy) ;;; ;("SGI" 1.36 sell) ;;; )) ;;; ;; do I own stock? ;;; (defvar *stock-something* t) ;;; (defun ign-erc-stock-player (proc parsed) ;;; (let* ((cmd (aref parsed 0)) ;;; (sspec (aref parsed 1)) ;;; (tgt (aref parsed 2)) ;;; (msg (aref parsed 3)) ;;; ;; sspec stuff ;;; (sender (erc-parse-user sspec)) ;;; (nick (nth 0 sender))) ;;; (when (and *stock-ai* ;;; (not (string= cmd "NOTICE")) ;;; (string= nick "Mojojojo") ;;; (string= tgt "#finance") ;;; (string-match "^\\*\\*\\* \\(.*\\)" msg)) ;;; (let* ((quotes-string (match-string 1 msg)) ;;; (quotes-string-list (split-string quotes-string ", ")) ;;; (quotes nil)) ;;; ;; loading QUOTES list with data ;;; (dolist (item quotes-string-list) ;;; (string-match "\\(.*\\)(\\(.*\\))" item) ;;; (let ((stock (match-string 1 item)) ;;; (price (car (read-from-string (match-string 2 item))))) ;;; (setf quotes (cons (cons stock price) quotes)))) ;;; ;; looking for action ;;; (dolist (item quotes) ;;; (let* ((stock (car item)) ;;; (price (cdr item))) ;;; (dolist (ai-item *stock-ai*) ;;; (when (string-equal (first ai-item) ;;; stock) ;;; (let* ((action (third ai-item)) ;;; (action-price (when ai-item ;;; (second ai-item))) ;;; (action-p nil)) ;;; (when (and price ai-item) ;;; (cond ((and (eq action 'sell) ;;; (>= price action-price) ;;; *stock-something*) ;;; ;; selling ;;; (erc-message "PRIVMSG" (concat "Mojojojo -st s " ;;; stock)) ;;; (setf *stock-something* nil) ;;; (setf action-p t)) ;;; ((and (eq action 'buy) ;;; (<= price action-price) ;;; (not *stock-something*)) ;;; ;; buying ;;; (erc-message "PRIVMSG" (concat "Mojojojo -st b " ;;; stock)) ;;; (setf *stock-something* t) ;;; (setf action-p t))) ;;; ;;(when action-p ;;; ;; (erc-message "PRIVMSG" "Mojojojo -st")) ;;; ))))))))) ;;; nil) ;;; ;(remove-hook 'erc-server-PRIVMSG-hook 'ign-erc-stock-player) ;;; ;(add-hook 'erc-server-PRIVMSG-hook 'ign-erc-stock-player) ;;; ;;; ...................................................................... ;;; ;;; ERC Icons ;;; ;; This hack inserts icons before nicknames in my ERC buffers, ;;; ;; effectively transforming the appearance of #debian.hu support channel ;;; ;; into a high-school AOL chatroom. Here is a sample: ;;; ;; http://ignotus.linuxforum.hu/stuff/yay.jpg ;;; ;; It looks for face informations in BBDB fields 'irc-nick' (nicks can ;;; ;; be separated by space) 'irc-face' (uuencoded PNG string!) and ;;; ;; 'irc-face-file' (pathname to a PNG file). ;;; (defun bbdb-search-irc-nick (nick) ;;; "returns record" ;;; (loop for record in (bbdb-records) ;;; when (member nick (split-string (bbdb-get-field record 'irc-nick) " ")) ;;; return record)) ;;; (defun ign-insert-irc-face () ;;; (goto-char (point-min)) ;;; (when (looking-at "^ +<\\(.*?\\)>") ;;; (let* ((nick (match-string 1)) ;;; (beg (1- (match-beginning 1))) ;;; (record (bbdb-search-irc-nick nick)) ;;; png) ;;; (when record ;;; (let ((face (bbdb-get-field record 'irc-face)) ;;; (face-file (bbdb-get-field record 'irc-face-file))) ;;; ;; BBDB returns an empty string instead nil ;;; (if (string= face "") ;;; (setq face nil) ;;; (setq png (gnus-convert-face-to-png face))) ;;; (when (string= face-file "") (setq face-file nil)) ;;; (when (or face face-file) ;;; (goto-char (point-min)) ;;; (w3m-insert-image (if (< (- beg 5) (line-beginning-position)) ;;; (line-beginning-position) ;;; (- beg 5)) ;;; (1- beg) ;;; (make-glyph ;;; (make-image-specifier ;;; (vector 'png (if face-file ;;; :file ;;; :data) ;;; (or face-file png))))))))))) ;;; (add-hook 'erc-insert-post-hook 'ign-insert-irc-face) ;;; ............................................. electric nick insert ... ;; When you speak with someone on an IRC channel you always put his or ;; her nick at the beginning of your line, that's evident. When people ;; don't do this that's not ignorance or something, just a sign that ;; their IRC clients lack functionality for inserting nicks ;; *effectively*. ;; Electric nick insertion is the best solution I found to this problem. ;; You have key ` (backquote), upon pressing, it inserts the last nick ;; that talked on that channel, after that it cycles through the nicks ;; of other people who recently talked. So in conversation most of the ;; time I just press backquote once or twice and I have the right nick ;; on the input line. ;; I wrote this code long time ago, it's hackish but works (at least ;; with my setup). :-) (defun ign-erc-last-talker (&optional pos) "Returns the last talker (not self)." (save-excursion (if (eq pos nil) (ign-erc-goto-prompt-beginning) (goto-char pos)) (ign-erc-last-talker-1))) (defun ign-erc-last-talker-1 () (let ((res (search-backward-regexp "^ *<\\(.*?\\)> " nil t))) (when res (if (not (string= (match-string 1) (erc-current-nick))) (match-string 1) (ign-erc-last-talker-1))))) (defun ign-erc-last-talkers (how-deep) (save-excursion (ign-erc-goto-prompt-beginning) (let ((i 0) results (nick (ign-erc-last-talker-1))) (while (and (not (eq nick nil)) ;nincs tobb talalat (< i how-deep)) (let ((res (member* nick results :test 'equal :key 'car))) (if res (incf (cadar res)) (setq results (append results (list (list nick 1))))) (incf i)) (setq nick (ign-erc-last-talker-1))) results))) (setq ign-erc-nick-comp-list nil) ;;(ign-erc-make-nickcomp-list) (defun ign-erc-make-nickcomp-list () ;;(when (not ign-erc-make-nickcomp-used) (setq ign-erc-make-nickcomp-used t) ;<- todo (let ((result-1 (ign-erc-last-talkers 28))) (setq result-1 (sort* (copy-seq result-1) '> :key 'cadr)) (if (> (length result-1) 5) (setq result-1 (subseq result-1 0 5))) (setq ign-erc-nick-comp-list (remove-duplicates (cons (ign-erc-last-talker) (mapcar 'car result-1)) :from-end t :test 'equal)) (setq ign-erc-nick-comp-list (remove "Mojojojo" ign-erc-nick-comp-list)) (mapc (lambda (x) (delete x ign-erc-nick-comp-list)) erc-keywords) (message (mapconcat (function identity) ign-erc-nick-comp-list " ")))) ;; chooses the next string that's not equal with the previous ;; (ign-erc-choose-next "trey") (defun ign-erc-choose-next (elt) (let ((res (second (member elt ign-erc-nick-comp-list)))) (if (eq res nil) (car ign-erc-nick-comp-list) res))) (defun ign-erc-electric-nickins () (interactive) (ign-erc-make-nickcomp-list) (save-excursion (when (search-backward-regexp (concat "^" erc-prompt " \\(.*?\\)" ;there erc-nick-completion-postfix) ;is a (line-beginning-position) ;nick t) ;already (goto-char (match-beginning 1)) (let ((next-nick (ign-erc-choose-next (buffer-substring (match-beginning 1) (match-end 1))))) (delete-region (match-beginning 1) (match-end 1)) (insert next-nick)))) (when (= (point) (ign-erc-prompt-position)) ; utolso beszelo (insert (ign-erc-last-talker) erc-nick-completion-postfix))) ;;; ;;; ................................................ ign-shorten-names ... ;;; ;; channel name shortening for erc-track.el ;;; (setf erc-track-shorten-function 'ign-erc-track-shorten-names) ;;; (defun ign-erc-track-shorten-names (channel-names) ;;; (let (results) ;;; (dolist (name channel-names) ;;; (push (cond ((string-equal name "#debian.hu") "#debHU") ;;; ((string-equal name "#kernelnewbies") "#krnln") ;;; ((string-equal name "#debian") "#deb") ;;; ((string-equal name "#debian-devel") "#ddev") ;;; ((string-equal name "#linux.hu") "#linHU") ;;; ((string-equal name "#trivia") "#triv") ;;; ((string-equal name "#finance") (erc-rem name) nil) ;<-don't track ;;; ((string-equal name "#emacs") "#emcs") ;;; ((string-equal name "#ValoVilag") "#VV") ;;; ((string-equal name "#sawfish") "#sawfsh") ;;; ((string-equal name "#bittorrent") "#BitT") ;;; ((string-equal name "#suprnova.org") "#SuprNov") ;;; ((string-equal name "localhost:54558") "prvFR") ;;; (t name)) ;;; results)) ;;; (setq results (remove nil results)) ;;; (nreverse results))) ;;; (defun erc-rem (chan) ;;; (erc-modified-channels-remove-buffer (get-buffer chan))) ;;; ;; (setq erc-modified-channels-string "") ;;; ;; (setq erc-modified-channels-alist nil) ;;; ;;; .................................................... track command ... ;;; ;; erc-track-mode is ultra-cool, but if I'm working on something it's a ;;; ;; big distractor, so with /track you can toggle its state (on/off). ;;; (defun erc-cmd-TRACK (line &optional force) ;;; (erc-display-line ;;; (erc-make-notice ;;; (if erc-track-mode ;;; "erc-track-mode OFF" "erc-track-mode ON")) 'active) ;;; (call-interactively 'erc-track-mode) ;;; t) ;;; ;; no arguments ;;; (put 'erc-cmd-TRACK 'do-not-parse-args t) ;;; ;; I need this redefining for /track command to not forget track status ;;; ;; informations during it is turned off. ;;; (define-erc-module track track-modified-channels ;;; "This mode tracks ERC channel buffers with activity." ;;; ((or global-mode-string ;;; (setq global-mode-string '(""))) ;;; (or (memq 'erc-modified-channels-string global-mode-string) ;;; (setq global-mode-string ;;; (append global-mode-string ;;; '(erc-modified-channels-string)))) ;;; (setq erc-modified-channels-string "") ;;; (erc-update-mode-line) ;;; (add-hook 'erc-insert-post-hook ;;; 'erc-track-modified-channels) ;;; (add-hook 'window-configuration-change-hook ;;; 'erc-modified-channels-update)) ;;; ((setq global-mode-string ;;; (delq 'erc-modified-channels-string global-mode-string)) ;;; ;; igno ;;; ; (remove-hook 'erc-insert-post-hook ;;; ; 'erc-track-modified-channels) ;;; ; (remove-hook 'window-configuration-change-hook ;;; ; 'erc-modified-channels-update))) ;;; )) ;;; ;;; ...................................................................... ;;; ;;; ign-erc-input-fill ;;; ;; This function refills inputed text, bind it to M-q. ;;; (defun ign-erc-input-fill () ;;; (interactive) ;;; (save-excursion ;;; (goto-char (+ 5 (ign-erc-prompt-beginnig-position))) ;todo <- messy:) ;;; (insert "\n") ;;; (let ((p (point)) ;;; (fill-column 400)) ;;; (fill-region-as-paragraph (point) (point-max)) ;;; (goto-char p) ;;; (delete-backward-char)))) ;;; (add-hook 'erc-mode-hook ;;; (lambda nil ;;; (define-key erc-mode-map [(meta q)] 'ign-erc-input-fill))) ;;; ;;; ...................................................................... ;;; ;;; erc syntax table hack ;;; ;; musthave ;;; (defun ign-syntax-table-abbrev-hack () ;;; "php->PHP but not .php->.PHP" ;;; (modify-syntax-entry ?\. "w" (syntax-table))) ;;; (add-hook 'erc-mode-hook 'ign-syntax-table-abbrev-hack) ;;; (add-hook 'message-mode-hook 'ign-syntax-table-abbrev-hack) ;;; ;;; ................................................... misc functions ... ;;; (defun ign-erc-goto-prompt () ;;; (goto-char (point-max)) ;;; (search-backward-regexp (concat "^" erc-prompt " ")) ;;; (goto-char (match-end 0))) (defun ign-erc-goto-prompt-beginning () (goto-char (point-max)) (search-backward-regexp (concat "^" erc-prompt " ")) (goto-char (match-beginning 0))) (defun ign-erc-prompt-position () (save-excursion (goto-char (point-max)) (search-backward-regexp (concat "^" erc-prompt " ")) (match-end 0))) ;;; (defun ign-erc-prompt-beginnig-position () ;;; (save-excursion ;;; (goto-char (point-max)) ;;; (search-backward-regexp (concat "^" erc-prompt " ")) ;;; (match-beginning 0))) ;;; ;;; ...................................................................... ;;; ;;; remove read-only property ;;; ;; This is better than (setq inhibit-read-only t) because that way the ;;; ;; ERC> prompt will stay read-only, I like that. ;;; (defun ign-erc-remove-read-only-prop () ;;; (remove-text-properties (point-min) (point-max) (list 'read-only))) ;;; (add-hook 'erc-insert-post-hook 'ign-erc-remove-read-only-prop) ;;; ;;; ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;;; ;;; my ERC-button.el dosen't work properly for me without this ;;; (defun erc-widget-press-button (elems el) ;;; (goto-char (widget-get elems :from)) ;;; (erc-button-press-button)) ;;; (defun erc-button-press-button () ;;; "Check text at point for a callback function. ;;; If the text at point has a `erc-callback' property, ;;; call it with the value of the `erc-data' text property." ;;; (interactive) ;;; (let* ((data (get-text-property (point) 'erc-data)) ;;; (fun (get-text-property (point) 'erc-callback))) ;;; (when fun ;;; (funcall fun (car data))))) ;<- igno ;;; ;;; ...................................................................... ;;; ;; When a privmsg occurs in a non-visible channel and our point is at ;;; ;; the end of the buffer then this function moves the point up one ;;; ;; line. That way when you switch to the buffer next time, the cursor ;;; ;; will show you where should you start catching up. Just press SPACE ;;; ;; as you read the text (that'll call scroll-up), at the end it will ;;; ;; jump after your prompt and will behave like a real space. If you ;;; ;; have highline.el it will turned on until you hit space first time. ;;; (defun ign-erc-hidden-move-up (proc parsed) ;;; (let* ((buffer (erc-get-buffer (aref parsed 2) proc)) ;;; (frame (ignore-errors (get-frame-for-buffer buffer)))) ;;; (when (and buffer ;;; (or (not (get-buffer-window buffer t)) ;;; (not frame) ;;; (member (frame-visible-p frame) ;;; '(hidden iconified)))) ;;; (with-current-buffer buffer ;;; (when (= (point) (point-max)) ;;; (forward-line -1) ;;; (set-window-point (get-buffer-window buffer t) ;;; (point)) ;;; (when (fboundp 'highline-on) ;;; (highline-on))))) ;;; nil)) ;;; (add-hook 'erc-server-PRIVMSG-hook 'ign-erc-hidden-move-up) ;;; ;(remove-hook 'erc-server-PRIVMSG-hook 'ign-erc-hidden-move-up) ;;; ;;; ........................................................ erc-space ... ;;; ;; Special SPC for erc buffers, if point is before erc-prompt, space ;;; ;; scrolls up, otherwise self-insert... ;;; (defun ign-erc-space () ;;; (interactive) ;;; (cond ((> (point) (ign-erc-prompt-position)) ;;; (self-insert-command 1)) ;;; ((= (point) (ign-erc-prompt-position)) ;;; (if (eq last-command 'ign-erc-space) ;;; (call-interactively 'erc-track-switch-buffer) ;;; (message "Press SPC again for erc-track-switch-buffer..."))) ;;; (t ;;; (condition-case nil ;;; (scroll-up-command) ;;; (error (progn ;;; (goto-char (point-max)) ;;; (recenter)))))) ;;; (setq erc-modified-channels-alist ;remove buffer from mod chan alist ;;; (remove* (current-buffer) erc-modified-channels-alist ;;; :key 'car)) ;;; (when (fboundp 'highline-off) ;turn off highline if avail ;;; (highline-off)) ;;; (erc-modified-channels-display)) ;;; (define-key erc-mode-map [(space)] 'ign-erc-space) ;;; ;;; ................................................... erc-track hack ... ;;; ;; erc track modification to show how many times your nick was ;;; ;; mentioned. Example: [#emacs:12c] 12 lines, 3 mentions (c is the ;;; ;; third letter of the alphabet) ;;; ;; Sorting is based on how much personal messages you got and how much ;;; ;; other messages there are. [erc-track-sort-by-activest] ;;; ;; another mod: check if frame with buffer is visible or not (hidden ;;; ;; or iconified) ;;; (defun erc-track-modified-channels () ;;; "Hook function for `erc-insert-post-hook' to check if the current ;;; buffer should be added to the modeline as a hidden, modified ;;; channel. Assumes it will only be called when current-buffer ;;; is in `erc-mode'." ;;; (let ((this-channel (erc-default-target))) ;;; (if (and (or (not (get-buffer-window (current-buffer) t)) ;;; (not (get-frame-for-buffer (current-buffer))) ;;; (member ;<- igno ;;; (frame-visible-p (get-frame-for-buffer (current-buffer))) ;;; '(nil hidden iconified))) ;;; (not (member this-channel erc-track-exclude)) ;;; (not (erc-message-type-member ;;; (or (erc-find-parsed-property) ;;; (point-min)) ;;; erc-track-exclude-types))) ;;; ;; If the active buffer is not visible (not shown in a ;;; ;; window), and not to be excluded, determine the kinds of ;;; ;; faces used in the current message, and add the buffer to ;;; ;; the erc-modified-channels-alist, if it is not already ;;; ;; there. If it the buffer is already on the list (in the ;;; ;; car), change its face attribute (in the cddr) if necessary. ;;; ;; See `erc-modified-channels-alist' for the exact data ;;; ;; structure used. ;;; (let ((faces (erc-faces-in (buffer-string))) ;;; (nick-p (save-excursion ;<- igno ;;; (goto-char (point-min)) ;<-igno ;;; (re-search-forward (erc-current-nick) nil t)))) ;<-igno ;;; (if (not (assq (current-buffer) erc-modified-channels-alist)) ;;; ;; Add buffer, faces and counts ;;; (setq erc-modified-channels-alist ;;; (cons (cons (current-buffer) ;;; (cons (cons 1 (if nick-p 1 0)) ;<-igno ;;; (erc-track-find-face faces))) ;;; erc-modified-channels-alist)) ;;; ;; Else modify the face for the buffer, if necessary. ;;; (when faces ;;; (let* ((cell (assq (current-buffer) ;;; erc-modified-channels-alist)) ;;; (old-face (cddr cell)) ;;; (new-face (erc-track-find-face ;;; (if old-face ;;; (cons old-face faces) ;;; faces)))) ;;; (setcdr cell (cons (cons (1+ (car (second cell))) ;;; (if nick-p (1+ (cdr (second cell))) ;;; (cdr (second cell)))) ;;; new-face))))) ;;; ;; And display it ;;; (erc-modified-channels-display)) ;;; ;; Else if the active buffer is the current buffer, remove it ;;; ;; from our list. ;;; (when (or (and (get-buffer-window (current-buffer) t) ;;; (get-frame-for-buffer (current-buffer)) ;<-igno v-igno ;;; (eq (frame-visible-p (get-frame-for-buffer (current-buffer))) ;;; t)) ;;; (and this-channel ;;; (assq (current-buffer) erc-modified-channels-alist) ;;; (member this-channel erc-track-exclude))) ;;; ;; Remove it from mode-line if buffer is visible or ;;; ;; channel was added to erc-track-exclude recently. ;;; (erc-modified-channels-remove-buffer (current-buffer)) ;;; (erc-modified-channels-display))))) ;;; ;; (ign-transform-int 0) ;;; (defun ign-transform-int (integer) ;;; (let ((alpha '(?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l))) ;;; (cond ((= integer 0) "") ;;; ((> integer (length alpha)) "Z") ;;; (t (char-to-string (nth (1- integer) alpha)))))) ;;; (defun erc-make-mode-line-buffer-name (string buffer &optional faces count) ;;; "Return STRING as a button that switches to BUFFER when clicked. ;;; If FACES are provided, color STRING with them." ;;; ;; We define a new sparse keymap every time, because 1. this data ;;; ;; structure is very small, the alternative would require us to ;;; ;; defvar a keymap, 2. the user is not interested in customizing it ;;; ;; (really?), 3. the defun needs to switch to BUFFER, so we would ;;; ;; need to save that value somewhere. ;;; (let ((map (make-sparse-keymap)) ;;; (name (if erc-track-showcount ;;; (concat string ;;; erc-track-showcount-string ;;; (int-to-string (car count)) ;<-igno ;;; (ign-transform-int (cdr count))) ;<-igno ;;; (copy-sequence string)))) ;;; (define-key map (vector 'mode-line 'mouse-2) ;;; `(lambda (e) ;;; (interactive "e") ;;; (save-selected-window ;;; (select-window ;;; (posn-window (event-start e))) ;;; (switch-to-buffer ,buffer)))) ;;; (put-text-property 0 (length name) 'local-map map name) ;;; (when (and faces erc-track-use-faces) ;;; (put-text-property 0 (length name) 'face faces name)) ;;; name)) ;;; (defun erc-track-sort-by-activest () ;;; "Sorts erc-modified-channels-alist by 'activeness'(count of not seen messages) ;;; +of channel" ;;; (setq erc-modified-channels-alist ;;; (sort erc-modified-channels-alist ;;; (lambda (a b) ;;; ;; igno ;;; (or (> (car (nth 1 a)) (car (nth 1 b))) ;;; (> (cdr (nth 1 a)) (cdr (nth 1 b)))))))) ;;; (defun erc-modified-channels-update () ;;; "This function updates the information in `erc-modified-channels-alist' ;;; according to buffer visibility. It calls ;;; `erc-modified-channels-display' at the end. This should usually be ;;; called via `window-configuration-change-hook'." ;;; (interactive) ;;; (unless erc-modified-channels-update-inside ;;; (let ((erc-modified-channels-update-inside t)) ;;; (mapcar (lambda (elt) ;;; (let ((buffer (car elt))) ;;; (when (or (not (bufferp buffer)) ;;; (not (buffer-live-p buffer)) ;;; (and (get-buffer-window buffer t);<-igno ;;; (eq (frame-visible-p;<-igno ;;; (get-frame-for-buffer buffer));<-igno ;;; t)));<-igno ;;; (erc-modified-channels-remove-buffer buffer)))) ;;; erc-modified-channels-alist) ;;; (erc-modified-channels-display)))) ;;; ;;; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ EOF @@@ (provide 'ignotus-erc-init)