erc-fill.el 6.8 KB

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