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