Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / lisp / erc / erc-fill.el
CommitLineData
597993cf
MB
1;;; erc-fill.el --- Filling IRC messages in various ways
2
acaf905b 3;; Copyright (C) 2001-2004, 2006-2012 Free Software Foundation, Inc.
597993cf
MB
4
5;; Author: Andreas Fuchs <asf@void.at>
6;; Mario Lang <mlang@delysid.org>
7;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcFilling
8
9;; This file is part of GNU Emacs.
10
4ee57b2a 11;; GNU Emacs is free software: you can redistribute it and/or modify
597993cf 12;; it under the terms of the GNU General Public License as published by
4ee57b2a
GM
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
597993cf
MB
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
4ee57b2a 22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
597993cf
MB
23
24;;; Commentary:
25
26;; This package implements filling of messages sent and received. Use
27;; `erc-fill-mode' to switch it on. Customize `erc-fill-function' to
28;; change the style.
29
30;;; Code:
31
32(require 'erc)
33(require 'erc-stamp); for the timestamp stuff
34
35(defgroup erc-fill nil
36 "Filling means to reformat long lines in different ways."
37 :group 'erc)
38
39;;;###autoload (autoload 'erc-fill-mode "erc-fill" nil t)
40(erc-define-minor-mode erc-fill-mode
41 "Toggle ERC fill mode.
ac6c8639
CY
42With a prefix argument ARG, enable ERC fill mode if ARG is
43positive, and disable it otherwise. If called from Lisp, enable
44the mode if ARG is omitted or nil.
45
46ERC fill mode is a global minor mode. When enabled, messages in
47the channel buffers are filled."
597993cf
MB
48 nil nil nil
49 :global t :group 'erc-fill
50 (if erc-fill-mode
51 (erc-fill-enable)
52 (erc-fill-disable)))
53
54(defun erc-fill-enable ()
55 "Setup hooks for `erc-fill-mode'."
56 (interactive)
57 (add-hook 'erc-insert-modify-hook 'erc-fill)
58 (add-hook 'erc-send-modify-hook 'erc-fill))
59
60(defun erc-fill-disable ()
61 "Cleanup hooks, disable `erc-fill-mode'."
62 (interactive)
63 (remove-hook 'erc-insert-modify-hook 'erc-fill)
64 (remove-hook 'erc-send-modify-hook 'erc-fill))
65
66(defcustom erc-fill-prefix nil
67 "Values used as `fill-prefix' for `erc-fill-variable'.
68nil means fill with space, a string means fill with this string."
69 :group 'erc-fill
70 :type '(choice (const nil) string))
71
72(defcustom erc-fill-function 'erc-fill-variable
73 "Function to use for filling messages.
74
75Variable Filling with an `erc-fill-prefix' of nil:
76
77<shortnick> this is a very very very long message with no
78 meaning at all
79
80Variable Filling with an `erc-fill-prefix' of four spaces:
81
82<shortnick> this is a very very very long message with no
83 meaning at all
84
85Static Filling with `erc-fill-static-center' of 27:
86
87 <shortnick> foo bar baz
88 <a-very-long-nick> foo bar baz quuuuux
89 <shortnick> this is a very very very long message with no
90 meaning at all
91
92These two styles are implemented using `erc-fill-variable' and
93`erc-fill-static'. You can, of course, define your own filling
94function. Narrowing to the region in question is in effect while your
95function is called."
96 :group 'erc-fill
97 :type '(choice (const :tag "Variable Filling" erc-fill-variable)
98 (const :tag "Static Filling" erc-fill-static)
99 function))
100
101(defcustom erc-fill-static-center 27
102 "Column around which all statically filled messages will be
103centered. This column denotes the point where the ' ' character
104between <nickname> and the entered text will be put, thus aligning
105nick names right and text left."
106 :group 'erc-fill
107 :type 'integer)
108
109(defcustom erc-fill-variable-maximum-indentation 17
110 "If we indent a line after a long nick, don't indent more then this
111characters. Set to nil to disable."
112 :group 'erc-fill
113 :type 'integer)
114
115(defcustom erc-fill-column 78
116 "The column at which a filled paragraph is broken."
117 :group 'erc-fill
118 :type 'integer)
119
120;;;###autoload
121(defun erc-fill ()
122 "Fill a region using the function referenced in `erc-fill-function'.
123You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
124 (unless (erc-string-invisible-p (buffer-substring (point-min) (point-max)))
125 (when erc-fill-function
83dc6995
MB
126 ;; skip initial empty lines
127 (goto-char (point-min))
128 (save-match-data
129 (while (and (looking-at "[ \t\n]*$")
130 (= (forward-line 1) 0))))
131 (unless (eobp)
132 (save-restriction
133 (narrow-to-region (point) (point-max))
134 (funcall erc-fill-function))))))
597993cf
MB
135
136(defun erc-fill-static ()
137 "Fills a text such that messages start at column `erc-fill-static-center'."
138 (save-match-data
139 (goto-char (point-min))
140 (looking-at "^\\(\\S-+\\)")
141 (let ((nick (match-string 1)))
142 (let ((fill-column (- erc-fill-column (erc-timestamp-offset)))
143 (fill-prefix (make-string erc-fill-static-center 32)))
144 (insert (make-string (max 0 (- erc-fill-static-center
145 (length nick) 1))
146 32))
147 (erc-fill-regarding-timestamp))
148 (erc-restore-text-properties))))
149
150(defun erc-fill-variable ()
151 "Fill from `point-min' to `point-max'."
152 (let ((fill-prefix erc-fill-prefix)
153 (fill-column (or erc-fill-column fill-column)))
154 (goto-char (point-min))
155 (if fill-prefix
156 (let ((first-line-offset (make-string (erc-timestamp-offset) 32)))
157 (insert first-line-offset)
158 (fill-region (point-min) (point-max) t t)
159 (goto-char (point-min))
160 (delete-char (length first-line-offset)))
161 (save-match-data
162 (let* ((nickp (looking-at "^\\(\\S-+\\)"))
163 (nick (if nickp
164 (match-string 1)
165 ""))
166 (fill-column (- erc-fill-column (erc-timestamp-offset)))
167 (fill-prefix (make-string (min (+ 1 (length nick))
168 (- fill-column 1)
169 (or erc-fill-variable-maximum-indentation
170 fill-column))
171 32)))
172 (erc-fill-regarding-timestamp))))
173 (erc-restore-text-properties)))
174
175(defun erc-fill-regarding-timestamp ()
176 "Fills a text such that messages start at column `erc-fill-static-center'."
177 (fill-region (point-min) (point-max) t t)
178 (goto-char (point-min))
179 (forward-line)
180 (indent-rigidly (point) (point-max) (erc-timestamp-offset)))
181
182(defun erc-timestamp-offset ()
183 "Get length of timestamp if inserted left."
184 (if (and (boundp 'erc-timestamp-format)
185 erc-timestamp-format
186 (eq erc-insert-timestamp-function 'erc-insert-timestamp-left)
187 (not erc-hide-timestamps))
188 (length (format-time-string erc-timestamp-format))
189 0))
190
597993cf
MB
191(provide 'erc-fill)
192
193;;; erc-fill.el ends here
194;; Local Variables:
195;; indent-tabs-mode: nil
196;; End:
197