about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el201
1 files changed, 201 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el
new file mode 100644
index 0000000000..d24e051f92
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el
@@ -0,0 +1,201 @@
+;;; lui-logging.el --- Logging support for lui
+
+;; Copyright (C) 2006  Jorgen Schaefer,
+;;               2012  Anthony Martinez
+
+;; Author: Anthony Martinez <pi+circe@pihost.us>
+
+;; This file is part of Lui.
+
+;; This program 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 3
+;; of the License, or (at your option) any later version.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This lui module enables logging. Lui applications can change the
+;; values of `lui-logging-format-arguments' to provide further
+;; possibilities of customizing `lui-logging-file-format' for users.
+
+;;; Code:
+
+(require 'lui-format)
+(require 'url-util)
+
+(defgroup lui-logging nil
+  "Logging support."
+  :prefix "lui-logging-"
+  :group 'lui)
+
+(defcustom lui-logging-format "[%T] {text}"
+  "The format used for log file entries.
+This is first passed through `format-time-string' and then through
+`lui-format'. The following format strings exist:
+
+  {text} - the text to be logged"
+  :type 'string
+  :group 'lui-logging)
+
+(defcustom lui-logging-directory "~/.logs"
+  "The directory where log files are stored."
+  :type 'directory
+  :group 'lui-logging)
+
+(defcustom lui-logging-file-format "{buffer}_%Y-%m-%d.txt"
+  "The format to be used for the log file name.
+This is first passed through `format-time-string', and then
+through `lui-format'. Possible lui format strings are:
+
+  {buffer} - the buffer name where the logging happened.
+
+Lui applications can provide further format strings. See
+`lui-logging-format-arguments' in the appropriate buffer."
+  :type 'string
+  :group 'lui-logging)
+
+(defcustom lui-logging-flush-delay 0
+  "The number of seconds to delay writing newly-received messages
+to disk. This can increase performance/decrease IO-wait at the
+cost of a little bit of safety."
+  :type 'integer
+  :group 'lui-logging)
+
+(defvar lui-logging-format-arguments nil
+  "A list of arguments to be passed to `lui-format'.
+This can be used to extend the formatting possibilities of the
+file name for lui applications.")
+(make-variable-buffer-local 'lui-logging-format-arguments)
+
+(defvar lui-logging-file-name-unreserved-chars
+  ;; All but '/' is fine actually, but also omit '%' because otherwise there's
+  ;; ambiguity between one introduced by encoding and a literal one.
+  '(?! ?\" ?# ?$ ?& ?` ?\( ?\) ?* ?+ ?,?: ?\; ?< ?= ?> ?? ?@?\[ ?\\ ?\] ?^ ?`
+       ?\{ ?| ?\})
+  "A list of characters that should not be percent-encoded by
+`url-hexify-string' while generating a logging file name.")
+
+(defvar lui-pending-logs
+  (make-hash-table :test 'equal)
+  "Storage for log messages awaiting write. It is structured as a
+hash table mapping filenames to a list-of-strings, which serves as
+a queue.")
+
+(defvar lui-logging-timer nil
+  "The timer used to flush lui-logged buffers")
+
+(defun lui-logging-delayed-p ()
+  (> lui-logging-flush-delay 0))
+
+(defun enable-lui-logging ()
+  "Enable lui logging for this buffer. Also create the log
+file's directory, should it not exist."
+  (interactive)
+  (add-hook 'lui-pre-output-hook 'lui-logging
+            nil t))
+
+(defun disable-lui-logging ()
+  "Disable lui logging for this buffer, and flush any pending
+logs to disk."
+  (interactive)
+  (remove-hook 'lui-pre-output-hook 'lui-logging t)
+  (lui-logging-flush))
+
+(defun enable-lui-logging-globally ()
+  "Enable lui logging for all Lui buffers.
+
+This affects current as well as future buffers."
+  (interactive)
+  (add-hook 'lui-mode-hook 'enable-lui-logging)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when lui-input-marker
+        (enable-lui-logging)))))
+
+(defun disable-lui-logging-globally ()
+  "Disable logging in all future Lui buffers.
+
+This affects current as well as future buffers."
+  (interactive)
+  (remove-hook 'lui-mode-hook 'enable-lui-logging)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when lui-input-marker
+        (disable-lui-logging)))))
+
+(defun lui-logging-file-name ()
+  "Create the name of the log file based on `lui-logging-file-format'."
+  (let* ((time-formatted (format-time-string lui-logging-file-format))
+         (buffer (let ((url-unreserved-chars
+                        (append url-unreserved-chars
+                                lui-logging-file-name-unreserved-chars))
+                       (downcased (downcase (buffer-name (current-buffer)))))
+                   (url-hexify-string downcased)))
+         (filename (apply 'lui-format
+                          time-formatted
+                          :buffer buffer
+                          lui-logging-format-arguments)))
+    (concat lui-logging-directory "/" filename)))
+
+(defun lui-logging-flush ()
+  "Flush out the lui-logging queue, and clear the timer set by
+`lui-logging'."
+  (maphash #'lui-logging-flush-file lui-pending-logs)
+  (clrhash lui-pending-logs)
+  (cancel-timer lui-logging-timer)
+  (setq lui-logging-timer nil))
+
+(defun lui-logging-write-to-log (file-name content)
+  "Actually perform a write to the logfile."
+  (let ((coding-system-for-write 'raw-text)
+        (dir (file-name-directory file-name)))
+    (when (not (file-directory-p dir))
+      (make-directory dir t))
+    (write-region content nil file-name t 'nomessage)))
+
+(defun lui-logging-flush-file (file-name queue)
+  "Consume the logging queue and write the content to the log
+file."
+  (let ((content (apply #'concat (nreverse queue))))
+    (lui-logging-write-to-log file-name content)))
+
+(defun lui-logging-format-string (text)
+  "Generate a string to be either directly written or enqueued."
+  (substring-no-properties
+   (lui-format
+    (format-time-string lui-logging-format)
+    :text text)))
+
+(defun lui-logging-enqueue (file-name text)
+  "Given a filename, push text onto its queue, and tickle the
+timer, if necessary."
+  (puthash file-name
+           (cons text (gethash file-name lui-pending-logs))
+           lui-pending-logs)
+  (when (null lui-logging-timer)
+    (setq lui-logging-timer
+          (run-with-timer lui-logging-flush-delay nil
+                          #'lui-logging-flush))))
+
+(defun lui-logging ()
+  "If output-queueing is enabled, append the to-be-logged string
+to the output queue. Otherwise, write directly to the logfile.
+This should be added to `lui-pre-output-hook' by way of
+`enable-lui-logging'."
+  (let ((text (lui-logging-format-string (buffer-string))))
+    (if (lui-logging-delayed-p)
+        (lui-logging-enqueue (lui-logging-file-name) text)
+      (lui-logging-write-to-log (lui-logging-file-name) text))))
+
+(provide 'lui-logging)
+;;; lui-logging.el ends here