-;;; erc-stamp.el --- Timestamping for Emacs IRC CLient
+;;; erc-stamp.el --- Timestamping for ERC messages
-;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 2002-2004, 2006-2012 Free Software Foundation, Inc.
;; Author: Mario Lang <mlang@delysid.org>
;; Keywords: comm, processes, timestamp
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs 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.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; 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., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
:group 'erc)
(defcustom erc-timestamp-format "[%H:%M]"
- "*If set to a string, messages will be timestamped.
+ "If set to a string, messages will be timestamped.
This string is processed using `format-time-string'.
Good examples are \"%T\" and \"%H:%M\".
:type '(choice (const nil)
(string)))
-(defcustom erc-insert-timestamp-function 'erc-insert-timestamp-right
- "*Function to use to insert timestamps.
+(defcustom erc-timestamp-format-left "\n[%a %b %e %Y]\n"
+ "If set to a string, messages will be timestamped.
+This string is processed using `format-time-string'.
+Good examples are \"%T\" and \"%H:%M\".
+
+This timestamp is used for timestamps on the left side of the
+screen when `erc-insert-timestamp-function' is set to
+`erc-insert-timestamp-left-and-right'.
+
+If nil, timestamping is turned off."
+ :group 'erc-stamp
+ :type '(choice (const nil)
+ (string)))
+
+(defcustom erc-timestamp-format-right " [%H:%M]"
+ "If set to a string, messages will be timestamped.
+This string is processed using `format-time-string'.
+Good examples are \"%T\" and \"%H:%M\".
+
+This timestamp is used for timestamps on the right side of the
+screen when `erc-insert-timestamp-function' is set to
+`erc-insert-timestamp-left-and-right'.
+
+If nil, timestamping is turned off."
+ :group 'erc-stamp
+ :type '(choice (const nil)
+ (string)))
+
+(defcustom erc-insert-timestamp-function 'erc-insert-timestamp-left-and-right
+ "Function to use to insert timestamps.
It takes a single argument STRING which is the final string
which all text-properties already appended. This function only cares about
inserting this string at the right position. Narrowing is in effect
while it is called, so (point-min) and (point-max) determine the region to
-operate on."
+operate on.
+
+You will probably want to set
+`erc-insert-away-timestamp-function' to the same value."
:group 'erc-stamp
- :type '(choice (const :tag "Right" erc-insert-timestamp-right)
+ :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right)
+ (const :tag "Right" erc-insert-timestamp-right)
(const :tag "Left" erc-insert-timestamp-left)
function))
(defcustom erc-away-timestamp-format "<%H:%M>"
- "*Timestamp format used when marked as being away.
+ "Timestamp format used when marked as being away.
If nil, timestamping is turned off when away unless `erc-timestamp-format'
is set.
:type '(choice (const nil)
(string)))
-(defcustom erc-insert-away-timestamp-function 'erc-insert-timestamp-right
- "*Function to use to insert the away timestamp.
+(defcustom erc-insert-away-timestamp-function
+ 'erc-insert-timestamp-left-and-right
+ "Function to use to insert the away timestamp.
See `erc-insert-timestamp-function' for details."
:group 'erc-stamp
- :type '(choice (const :tag "Right" erc-insert-timestamp-right)
+ :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right)
+ (const :tag "Right" erc-insert-timestamp-right)
(const :tag "Left" erc-insert-timestamp-left)
function))
(defcustom erc-hide-timestamps nil
- "*If non-nil, timestamps will be invisible.
+ "If non-nil, timestamps will be invisible.
This is useful for logging, because, although timestamps will be
hidden, they will still be present in the logs."
:type 'boolean)
(defcustom erc-echo-timestamps nil
- "*If non-nil, print timestamp in the minibuffer when point is moved.
+ "If non-nil, print timestamp in the minibuffer when point is moved.
Using this variable, you can turn off normal timestamping,
and simply move point to an irc message to see its timestamp
printed in the minibuffer."
:type 'boolean)
(defcustom erc-echo-timestamp-format "Timestamped %A, %H:%M:%S"
- "*Format string to be used when `erc-echo-timestamps' is non-nil.
+ "Format string to be used when `erc-echo-timestamps' is non-nil.
This string specifies the format of the timestamp being echoed in
the minibuffer."
:group 'erc-stamp
:type 'string)
(defcustom erc-timestamp-intangible t
- "*Whether the timestamps should be intangible, i.e. prevent the point
+ "Whether the timestamps should be intangible, i.e. prevent the point
from entering them and instead jump over them."
:group 'erc-stamp
:type 'boolean)
-(defface erc-timestamp-face '((t (:bold t :foreground "green")))
+(defface erc-timestamp-face '((t :weight bold :foreground "green"))
"ERC timestamp face."
:group 'erc-faces)
(error "Timestamp function unbound"))
(when (and (fboundp erc-insert-away-timestamp-function)
erc-away-timestamp-format
- (with-current-buffer (erc-server-buffer) erc-away)
+ (erc-away-time)
(not erc-timestamp-format))
(funcall erc-insert-away-timestamp-function
(erc-format-timestamp ct erc-away-timestamp-format)))
"Last timestamp inserted into the buffer.")
(make-variable-buffer-local 'erc-timestamp-last-inserted)
+(defvar erc-timestamp-last-inserted-left nil
+ "Last timestamp inserted into the left side of the buffer.
+This is used when `erc-insert-timestamp-function' is set to
+`erc-timestamp-left-and-right'")
+(make-variable-buffer-local 'erc-timestamp-last-inserted-left)
+
+(defvar erc-timestamp-last-inserted-right nil
+ "Last timestamp inserted into the right side of the buffer.
+This is used when `erc-insert-timestamp-function' is set to
+`erc-timestamp-left-and-right'")
+(make-variable-buffer-local 'erc-timestamp-last-inserted-right)
+
(defcustom erc-timestamp-only-if-changed-flag t
- "*Insert timestamp only if its value changed since last insertion.
+ "Insert timestamp only if its value changed since last insertion.
If `erc-insert-timestamp-function' is `erc-insert-timestamp-left', a
string of spaces which is the same size as the timestamp is added to
the beginning of the line in its place. If you use
:type 'boolean)
(defcustom erc-timestamp-right-column nil
- "*If non-nil, the column at which the timestamp is inserted,
+ "If non-nil, the column at which the timestamp is inserted,
if the timestamp is to be printed to the right. If nil,
`erc-insert-timestamp-right' will use other means to determine
the correct column."
(integer :tag "Column number")
(const :tag "Unspecified" nil)))
-(defcustom erc-timestamp-right-align-by-pixel nil
- "*If non-nil, insert the right timestamp based on a pixel value.
-This is needed when variable-width text precedes a timestamp.
+(defcustom erc-timestamp-use-align-to (and (not (featurep 'xemacs))
+ (>= emacs-major-version 22)
+ (eq window-system 'x))
+ "If non-nil, use the :align-to display property to align the stamp.
+This gives better results when variable-width characters (like
+Asian language characters and math symbols) precede a timestamp.
Unfortunately, it only works in Emacs 22 and when using the X
-Window System."
+Window System.
+
+A side effect of enabling this is that there will only be one
+space before a right timestamp in any saved logs."
:group 'erc-stamp
:type 'boolean)
(s (if ignore-p (make-string len ? ) string)))
(unless ignore-p (setq erc-timestamp-last-inserted string))
(erc-put-text-property 0 len 'field 'erc-timestamp s)
+ (erc-put-text-property 0 len 'invisible 'timestamp s)
(insert s)))
-(defun erc-insert-aligned (string pos &optional fallback)
- "Insert STRING based on a fraction of the width of the buffer.
-Fraction is roughly (/ POS (window-width)).
+(defun erc-insert-aligned (string pos)
+ "Insert STRING at the POSth column.
-If `erc-timestamp-right-align-by-pixel' is nil, use
-\(- POS FALLBACK) to determine how many spaces to insert."
- (if (not erc-timestamp-right-align-by-pixel)
- (insert (make-string (- pos fallback) ? ) string)
+If `erc-timestamp-use-align-to' is t, use the :align-to display
+property to get to the POSth column."
+ (if (not erc-timestamp-use-align-to)
+ (indent-to pos)
(insert " ")
- (let ((offset (floor (* (/ (1- pos) (window-width) 1.0)
- (nth 2 (window-inside-pixel-edges))))))
- (put-text-property (1- (point)) (point) 'display
- `(space :align-to (,offset))))
- (insert string)))
+ (put-text-property (1- (point)) (point) 'display
+ (list 'space ':align-to pos)))
+ (insert string))
+
+;; Silence byte-compiler
+(defvar erc-fill-column)
(defun erc-insert-timestamp-right (string)
"Insert timestamp on the right side of the screen.
(goto-char (point-max))
(forward-char -1);; before the last newline
(let* ((current-window (get-buffer-window (current-buffer)))
+ (str-width (string-width string))
(pos (cond
- (erc-timestamp-right-column
- (+ erc-timestamp-right-column (length string)))
+ (erc-timestamp-right-column erc-timestamp-right-column)
((and (boundp 'erc-fill-mode)
erc-fill-mode
- (boundp 'erc-fill-column))
- (1+ erc-fill-column))
- (current-window
- (- (window-width current-window)
- 1))
+ (boundp 'erc-fill-column)
+ erc-fill-column)
+ (1+ (- erc-fill-column str-width)))
(fill-column
- (1+ fill-column))
+ (1+ (- fill-column str-width)))
(t
- (- (window-width)
- 1))))
+ (- (window-width) str-width 1))))
(from (point))
(col (current-column))
indent)
- ;; deal with variable-width characters
- (setq pos (- pos (string-width string))
- ;; the following is a kludge that works with most
- ;; international input
- col (+ col (ceiling (/ (- col (- (point) (point-at-bol))) 1.6))))
+ ;; The following is a kludge used to calculate whether to move
+ ;; to the next line before inserting a stamp. It allows for
+ ;; some margin of error if what is displayed on the line differs
+ ;; from the number of characters on the line.
+ (setq col (+ col (ceiling (/ (- col (- (point) (point-at-bol))) 1.6))))
(if (< col pos)
- (erc-insert-aligned string pos col)
+ (erc-insert-aligned string pos)
(newline)
- (setq from (point))
(indent-to pos)
+ (setq from (point))
(insert string))
- (erc-put-text-property from (1+ (point)) 'field 'erc-timestamp)
- (erc-put-text-property from (1+ (point)) 'rear-nonsticky t)
+ (erc-put-text-property from (point) 'field 'erc-timestamp)
+ (erc-put-text-property from (point) 'rear-nonsticky t)
(when erc-timestamp-intangible
(erc-put-text-property from (1+ (point)) 'intangible t)))))
+(defun erc-insert-timestamp-left-and-right (string)
+ "This is another function that can be assigned to
+`erc-insert-timestamp-function'. If the date is changed, it will
+print a blank line, the date, and another blank line. If the time is
+changed, it will then print it off to the right."
+ (let* ((ct (current-time))
+ (ts-left (erc-format-timestamp ct erc-timestamp-format-left))
+ (ts-right (erc-format-timestamp ct erc-timestamp-format-right)))
+ ;; insert left timestamp
+ (unless (string-equal ts-left erc-timestamp-last-inserted-left)
+ (goto-char (point-min))
+ (erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp ts-left)
+ (insert ts-left)
+ (setq erc-timestamp-last-inserted-left ts-left))
+ ;; insert right timestamp
+ (let ((erc-timestamp-only-if-changed-flag t)
+ (erc-timestamp-last-inserted erc-timestamp-last-inserted-right))
+ (erc-insert-timestamp-right ts-right)
+ (setq erc-timestamp-last-inserted-right ts-right))))
+
;; for testing: (setq erc-timestamp-only-if-changed-flag nil)
(defun erc-format-timestamp (time format)
(setq erc-hide-timestamps nil)
(erc-munge-invisibility-spec))
+(defun erc-toggle-timestamps ()
+ "Hide or show timestamps in ERC buffers.
+
+Note that timestamps can only be shown for a message using this
+function if `erc-timestamp-format' was set and timestamping was
+enabled when the message was inserted."
+ (interactive)
+ (if erc-hide-timestamps
+ (setq erc-hide-timestamps nil)
+ (setq erc-hide-timestamps t))
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (erc-munge-invisibility-spec)))
+ (erc-buffer-list)))
+
(defun erc-echo-timestamp (before now)
"Print timestamp text-property of an IRC message.
Argument BEFORE is where point was before it got moved and
(when erc-echo-timestamps
(let ((stamp (get-text-property now 'timestamp)))
(when stamp
- (message (format-time-string erc-echo-timestamp-format
- stamp))))))
+ (message "%s" (format-time-string erc-echo-timestamp-format
+ stamp))))))
(provide 'erc-stamp)
;; tab-width: 8
;; End:
-;; arch-tag: 9f6d31bf-61ba-45c5-bdbf-56331486ea27