|
From: Benjamin R. <rut...@ci...> - 2003-09-03 14:45:22
|
Mario Lang <ml...@de...> writes:
> So, if anyone here has any pending code to commit, please do so in the
> next few days. Also, if you could spend some time on trying to find and
> fix remaining bugs, that would be helpful too. I will be uploading a new
> CVS snapshot to the Debian archives next week.
Any chance that erc-cite.el could be checked in? I use it almost
daily without any problems, consider it stable, and expect that others
could benefit from it. The latest version is included below for
convenience; it actually has not changed since I last posted it in
this group's message <wc3...@ga...>.
As a reminder, you can enable this package by doing (require
'erc-cite), which then binds C-c C-a in erc-mode-map. Concurrent with
adding erc-cite.el to the repository should be removing the redundant
C-c C-a binding from erc.el (C-a runs erc-bol anyway).
Thanks, let me know of your decision to include it or not.
;; erc-cite.el -- Cite messages written by previous IRC users
;; Copyright (C) 2003 Benjamin Rutt <br...@bl...>
;; Author: Benjamin Rutt <br...@bl...>
;; Keywords: comm, convenience
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; Ever have trouble knowing which IRC message is in response to which
;; previous message? I realize that there is a standard of the
;; prefixing a message with nickname: style messages, e.g. 'foo'
;; saying things in response to user 'bar' as follows:
;;
;; <foo> bar: may God have mercy on your soul.
;;
;; But that just doesn't cut it when user 'bar' has written many
;; messages previously. Exactly which message made user 'foo' so
;; upset?
;;
;; That's where this package comes in. This package allows you to
;; cite messages written by previous IRC users. To enable this
;; package, do a
;;
;; (require 'erc-cite)
;;
;; In order to cite a message written previously in an IRC channel,
;; simply move point up so that it is placed on one of the lines of
;; the previous message you want to cite, and press the key sequence
;;
;; C-c C-a
;;
;; which will place the text of that message between citation marks on
;; the current ERC prompt line, and place point at the end of the
;; prompt, allowing you to respond to that particular message, with
;; everyone in the channel knowing exactly which message you are
;; responding to.
;;
;; Here is an example of user 'bar' citing user 'foo'
;;
;; <foo> I wrote this
;; <foo> then I wrote thsi
;; <foo> and then I wrote this
;; <bar> "<foo> then I wrote thsi" <-- you made a spelling error
;;
;; Whether or not the <foo> is included in the citation can be
;; customized; see the variable `erc-cite-build-citation-function'.
(require 'erc)
(defconst erc-cite-version "$Revision: 1.0 $"
"ERC cite revision")
(defgroup erc-cite nil
"Cite messages written by previous IRC users"
:group 'erc)
(defcustom erc-cite-start "\""
"*Beginning of ERC citation prefix."
:group 'erc-cite
:type 'string)
(defcustom erc-cite-end "\" <-- "
"*End of ERC citation prefix."
:group 'erc-cite
:type 'string)
(defcustom erc-cite-build-citation-function 'erc-cite-build-citation-with-nick
"*A function that builds the citation string.
The function must take two arguments: NICK and MESSAGE.
NICK is the IRC nickname who authored the message that is being cited.
MESSAGE is the IRC message that is being cited.
The function should return a string that will be then placed in
the current ERC input line, with point placed at the end.
Two builtin functions are
`erc-cite-build-citation-with-nick' (the default) and
`erc-cite-build-citation-without-nick'.
Here is an example of a custom function, which uses the
without-nick style in one channel and the with-nick style in all
others:
(defun erc-cite-build-citation-with-nick-maybe (nick message)
(if (equal (buffer-name) \"#oneononechatting\")
(erc-cite-build-citation-without-nick nick message)
(erc-cite-build-citation-with-nick nick message)))"
:group 'erc-cite
:type 'function)
(defun erc-cite ()
"Place the cited message from the current line into the current
input line."
(interactive)
(cond
((erc-server-buffer-p) (message "erc-cite only works in channel buffers"))
((eq erc-fill-function 'erc-fill-variable) (erc-cite-erc-fill-variable))
((eq erc-fill-function 'erc-fill-static) (erc-cite-erc-fill-static))
(t (message "erc-cite is not implemented for your `erc-fill-function'"))))
(defun erc-cite-build-citation-with-nick (nick message)
(concat erc-cite-start "<" nick "> " message erc-cite-end))
(defun erc-cite-build-citation-without-nick (nick message)
(concat erc-cite-start message erc-cite-end))
(defun erc-cite-abort (orig-point)
(message "Nothing to cite")
(goto-char orig-point))
(defun erc-cite-erc-fill-variable ()
"Impementation of citing when `erc-fill-variable' is being used."
(let ((orig-point (point))
(cite-str "")
(nick nil))
;; look on this line or upwards for the start of an IRC message
(beginning-of-line)
;; rule out being on the erc-prompt line immediately.
(if (looking-at (regexp-quote erc-prompt))
(erc-cite-abort orig-point)
(while (and (not (looking-at "<.*> "))
(not (looking-at "^\\* ")) ;; /me
(not (looking-at (regexp-quote erc-notice-prefix)))
(not (eq (point) (point-min))))
(previous-line 1)
(beginning-of-line))
(if (or (looking-at "^\\* ") ;; /me
(looking-at (regexp-quote erc-notice-prefix))
(eq (point) (point-min)))
(erc-cite-abort orig-point)
(forward-char 1)
(setq nick
(buffer-substring-no-properties (point)
(progn
(while (not (looking-at "> "))
(forward-char 1))
(point))))
(forward-char 2)
(setq cite-str
(concat cite-str
(erc-trim-string
(buffer-substring-no-properties
(point) (progn (end-of-line) (point))))))
(next-line 1)
(beginning-of-line)
;; keep concatenating lines until you reach the end of the
;; message
(while (and (not (looking-at "<"))
(not (looking-at "^\\* ")) ;; /me
(not (looking-at (regexp-quote erc-prompt)))
(not (looking-at (regexp-quote erc-notice-prefix))))
(setq cite-str
(concat cite-str " "
(erc-trim-string
(buffer-substring-no-properties
(point) (progn (end-of-line) (point))))))
(next-line 1)
(beginning-of-line))
(erc-replace-current-command
(funcall erc-cite-build-citation-function nick cite-str))
;; Avoid the wretched style of "top posting". Make the new
;; content go at the end of what is being cited.
(end-of-line)))))
(defun erc-cite-erc-fill-static-left ()
(let ((beg nil)
(end nil))
(save-excursion
(beginning-of-line)
(setq beg (point))
(forward-char (1+ erc-fill-static-center))
(setq end (point))
(if (= (count-lines beg end) 1)
(buffer-substring-no-properties beg end)
nil))))
(defun erc-cite-erc-fill-static-right ()
(let ((beg nil)
(end nil))
(save-excursion
(beginning-of-line)
(forward-char (1+ erc-fill-static-center))
(setq beg (point))
(end-of-line)
(setq end (point))
(if (= (count-lines beg end) 1)
(buffer-substring-no-properties beg end)
nil))))
(defun erc-cite-erc-fill-static ()
"Impementation of citing when `erc-fill-static' is being used."
(let ((orig-point (point))
(cite-str "")
(done nil)
(not-citing nil)
(nick nil)
(left nil)
(left-notice-regexp
(concat "^ +" (regexp-quote erc-notice-prefix) "$"))
(left-me-regexp "^ +\\* $")
(left-nick-regexp "^ *<.*> $"))
;; look on this line or upwards for the start of an IRC message
(beginning-of-line)
(if (looking-at (regexp-quote erc-prompt))
(erc-cite-abort orig-point)
(setq left (erc-cite-erc-fill-static-left))
;; ignore empty lines
(if (not left)
(erc-cite-abort orig-point)
(while (not done)
(cond
;; ignore notices
((string-match left-notice-regexp left)
(setq done t
not-citing t))
;; ignore /me
((string-match left-me-regexp left)
(setq done t
not-citing t))
((string-match left-nick-regexp left)
(setq done t))
(t
(previous-line 1)
(setq left (erc-cite-erc-fill-static-left)))))
(if not-citing
(erc-cite-abort orig-point)
;; by now, point is on the first line of the cited message
(setq cite-str (concat cite-str (erc-cite-erc-fill-static-right)))
(setq nick (progn (beginning-of-line)
(while (not (looking-at "<"))
(forward-char 1))
(forward-char 1)
(buffer-substring-no-properties
(point)
(progn
(while (not (looking-at "> "))
(forward-char 1))
(point)))))
(forward-line 1)
(beginning-of-line)
;; from the first line, get all the lines of the message
(while (and (not (looking-at (regexp-quote erc-prompt)))
(setq left (erc-cite-erc-fill-static-left))
(not (string-match left-notice-regexp left))
(not (string-match left-me-regexp left))
(not (string-match left-nick-regexp left)))
(setq cite-str
(concat cite-str " " (erc-cite-erc-fill-static-right)))
(forward-line 1)
(beginning-of-line))
(erc-replace-current-command
(funcall erc-cite-build-citation-function nick cite-str))
;; Avoid the wretched style of "top posting". Make the new
;; content go at the end of what is being cited.
(end-of-line))))))
(define-key erc-mode-map "\C-c\C-a" 'erc-cite)
(provide 'erc-cite)
;;; erc-cite.el ends here
|