Compare commits
3 commits
2d28bdf85e
...
e5952e241f
Author | SHA1 | Date | |
---|---|---|---|
KemoNine | e5952e241f | ||
KemoNine | 356980b7ce | ||
KemoNine | e3d0589559 |
102
org/elpa/alert-20221213.1619/alert-autoloads.el
Normal file
102
org/elpa/alert-20221213.1619/alert-autoloads.el
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
;;; alert-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (directory-file-name
|
||||||
|
(or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;### (autoloads nil "alert" "alert.el" (0 0 0 0))
|
||||||
|
;;; Generated autoloads from alert.el
|
||||||
|
|
||||||
|
(autoload 'alert-add-rule "alert" "\
|
||||||
|
Programmatically add an alert configuration rule.
|
||||||
|
|
||||||
|
Normally, users should custoimze `alert-user-configuration'.
|
||||||
|
This facility is for module writers and users that need to do
|
||||||
|
things the Lisp way.
|
||||||
|
|
||||||
|
Here is a rule the author currently uses with ERC, so that the
|
||||||
|
fringe gets colored whenever people chat on BitlBee:
|
||||||
|
|
||||||
|
\(alert-add-rule :status \\='(buried visible idle)
|
||||||
|
:severity \\='(moderate high urgent)
|
||||||
|
:mode \\='erc-mode
|
||||||
|
:predicate
|
||||||
|
#\\='(lambda (info)
|
||||||
|
(string-match (concat \"\\\\`[^&].*@BitlBee\\\\\\='\")
|
||||||
|
(erc-format-target-and/or-network)))
|
||||||
|
:persistent
|
||||||
|
#\\='(lambda (info)
|
||||||
|
;; If the buffer is buried, or the user has been
|
||||||
|
;; idle for `alert-reveal-idle-time' seconds,
|
||||||
|
;; make this alert persistent. Normally, alerts
|
||||||
|
;; become persistent after
|
||||||
|
;; `alert-persist-idle-time' seconds.
|
||||||
|
(memq (plist-get info :status) \\='(buried idle)))
|
||||||
|
:style \\='fringe
|
||||||
|
:continue t)
|
||||||
|
|
||||||
|
\(fn &key SEVERITY STATUS MODE CATEGORY TITLE MESSAGE PREDICATE ICON (STYLE alert-default-style) PERSISTENT CONTINUE NEVER-PERSIST APPEND)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'alert "alert" "\
|
||||||
|
Alert the user that something has happened.
|
||||||
|
MESSAGE is what the user will see. You may also use keyword
|
||||||
|
arguments to specify additional details. Here is a full example:
|
||||||
|
|
||||||
|
\(alert \"This is a message\"
|
||||||
|
:severity \\='high ;; The default severity is `normal'
|
||||||
|
:title \"Title\" ;; An optional title
|
||||||
|
:category \\='example ;; A symbol to identify the message
|
||||||
|
:mode \\='text-mode ;; Normally determined automatically
|
||||||
|
:buffer (current-buffer) ;; This is the default
|
||||||
|
:data nil ;; Unused by alert.el itself
|
||||||
|
:persistent nil ;; Force the alert to be persistent;
|
||||||
|
;; it is best not to use this
|
||||||
|
:never-persist nil ;; Force this alert to never persist
|
||||||
|
:id \\='my-id) ;; Used to replace previous message of
|
||||||
|
;; the same id in styles that support it
|
||||||
|
:style \\='fringe) ;; Force a given style to be used;
|
||||||
|
;; this is only for debugging!
|
||||||
|
:icon \\=\"mail-message-new\" ;; if style supports icon then add icon
|
||||||
|
;; name or path here
|
||||||
|
|
||||||
|
If no :title is given, the buffer-name of :buffer is used. If
|
||||||
|
:buffer is nil, it is the current buffer at the point of call.
|
||||||
|
|
||||||
|
:data is an opaque value which modules can pass through to their
|
||||||
|
own styles if they wish.
|
||||||
|
|
||||||
|
Here are some more typical examples of usage:
|
||||||
|
|
||||||
|
;; This is the most basic form usage
|
||||||
|
(alert \"This is an alert\")
|
||||||
|
|
||||||
|
;; You can adjust the severity for more important messages
|
||||||
|
(alert \"This is an alert\" :severity \\='high)
|
||||||
|
|
||||||
|
;; Or decrease it for purely informative ones
|
||||||
|
(alert \"This is an alert\" :severity \\='trivial)
|
||||||
|
|
||||||
|
;; Alerts can have optional titles. Otherwise, the title is the
|
||||||
|
;; buffer-name of the (current-buffer) where the alert originated.
|
||||||
|
(alert \"This is an alert\" :title \"My Alert\")
|
||||||
|
|
||||||
|
;; Further, alerts can have categories. This allows users to
|
||||||
|
;; selectively filter on them.
|
||||||
|
(alert \"This is an alert\" :title \"My Alert\"
|
||||||
|
:category \\='some-category-or-other)
|
||||||
|
|
||||||
|
\(fn MESSAGE &key (SEVERITY \\='normal) TITLE ICON CATEGORY BUFFER MODE DATA STYLE PERSISTENT NEVER-PERSIST ID)" nil nil)
|
||||||
|
|
||||||
|
(register-definition-prefixes "alert" '("alert-" "x-urgen"))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; coding: utf-8
|
||||||
|
;; End:
|
||||||
|
;;; alert-autoloads.el ends here
|
2
org/elpa/alert-20221213.1619/alert-pkg.el
Normal file
2
org/elpa/alert-20221213.1619/alert-pkg.el
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
;;; Generated package description from alert.el -*- no-byte-compile: t -*-
|
||||||
|
(define-package "alert" "20221213.1619" "Growl-style notification system for Emacs" '((gntp "0.1") (log4e "0.3.0") (cl-lib "0.5")) :commit "c762380ff71c429faf47552a83605b2578656380" :authors '(("John Wiegley" . "jwiegley@gmail.com")) :maintainer '("John Wiegley" . "jwiegley@gmail.com") :keywords '("notification" "emacs" "message") :url "https://github.com/jwiegley/alert")
|
1221
org/elpa/alert-20221213.1619/alert.el
Normal file
1221
org/elpa/alert-20221213.1619/alert.el
Normal file
File diff suppressed because it is too large
Load diff
29
org/elpa/alert-toast-20220312.229/alert-toast-autoloads.el
Normal file
29
org/elpa/alert-toast-20220312.229/alert-toast-autoloads.el
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
;;; alert-toast-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (directory-file-name
|
||||||
|
(or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;### (autoloads nil "alert-toast" "alert-toast.el" (0 0 0 0))
|
||||||
|
;;; Generated autoloads from alert-toast.el
|
||||||
|
|
||||||
|
(autoload 'alert-toast-notify "alert-toast" "\
|
||||||
|
Send INFO using Windows 10 toast notification.
|
||||||
|
Handles :ICON, :SEVERITY, :PERSISTENT, :NEVER-PERSIST, :TITLE and
|
||||||
|
:MESSAGE keywords from INFO plist.
|
||||||
|
|
||||||
|
\(fn INFO)" nil nil)
|
||||||
|
|
||||||
|
(register-definition-prefixes "alert-toast" '("alert-toast-"))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; coding: utf-8
|
||||||
|
;; End:
|
||||||
|
;;; alert-toast-autoloads.el ends here
|
2
org/elpa/alert-toast-20220312.229/alert-toast-pkg.el
Normal file
2
org/elpa/alert-toast-20220312.229/alert-toast-pkg.el
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
;;; Generated package description from alert-toast.el -*- no-byte-compile: t -*-
|
||||||
|
(define-package "alert-toast" "20220312.229" "Windows 10 toast notifications" '((emacs "25.1") (alert "1.2") (f "0.20.0") (s "1.12.0")) :commit "96c88c93c1084de681700f655223142ee0eb944a" :authors '(("Grzegorz Kowzan" . "grzegorz@kowzan.eu")) :maintainer '("Grzegorz Kowzan" . "grzegorz@kowzan.eu") :url "https://github.com/gkowzan/alert-toast")
|
316
org/elpa/alert-toast-20220312.229/alert-toast.el
Normal file
316
org/elpa/alert-toast-20220312.229/alert-toast.el
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
;;; alert-toast.el --- Windows 10 toast notifications -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright 2020, 2022 Grzegorz Kowzan
|
||||||
|
|
||||||
|
;; Author: Grzegorz Kowzan <grzegorz@kowzan.eu>
|
||||||
|
;; Created: 25 Oct 2020
|
||||||
|
;; Updated: 25 Mar 2022
|
||||||
|
;; Version: 1.0.0
|
||||||
|
;; Package-Version: 20220312.229
|
||||||
|
;; Package-Commit: 96c88c93c1084de681700f655223142ee0eb944a
|
||||||
|
;; Package-Requires: ((emacs "25.1") (alert "1.2") (f "0.20.0") (s "1.12.0"))
|
||||||
|
;; Url: https://github.com/gkowzan/alert-toast
|
||||||
|
|
||||||
|
;; 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 2, 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 GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
;; Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This package defines a new alert style (`toast') for alert.el using Windows
|
||||||
|
;; 10 toast notifications. It works with native Windows 10 Emacs versions and
|
||||||
|
;; with Emacs run under Windows Subsystem for Linux (WSL) or under Cygwin. These
|
||||||
|
;; notifications are limited to a single-line title and four lines of text.
|
||||||
|
;; Longer text can be passed but it will be truncated by Windows 10.
|
||||||
|
;;
|
||||||
|
;; * Icons
|
||||||
|
;; Icons located on network shares are not supported. This includes icons on the
|
||||||
|
;; WSL virtual drive, therefore for Emacs running under WSL the default Emacs
|
||||||
|
;; icon is copied to C:\Users\<user>\AppData\Local\Emacs-Toast\Emacs.png. PNG
|
||||||
|
;; version is used because toast notifications render SVG graphics as tiny and
|
||||||
|
;; put them in top left corner of the notification.
|
||||||
|
|
||||||
|
;; Under WSL or Cygwin, a path to a custom icon should be given as a WSL/Cygwin
|
||||||
|
;; path (/mnt/c/... or /cygdrive/c/...) instead of a Windows path (C:\\...).
|
||||||
|
;;
|
||||||
|
;; * Priorities
|
||||||
|
;; Looking at Windows.UI.Notifications API, toast notifications seem to support
|
||||||
|
;; 2 priority levels: High and Default. Mapping between alert.el priorities and
|
||||||
|
;; these levels is defined by `alert-toast-priorities'.
|
||||||
|
;;
|
||||||
|
;; * Bugs
|
||||||
|
;; There is an issue in WSL where wslhost.exe dies for no discernible reason,
|
||||||
|
;; which prevents accessing Windows partitions and executables
|
||||||
|
;; (https://github.com/microsoft/WSL/issues/6161). If this happens then you
|
||||||
|
;; should see powershell.exe process failing to start. This will obviously
|
||||||
|
;; prevent this package from working. The only known workaround is to call `wsl
|
||||||
|
;; --shutdown' and start WSL again.
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'f)
|
||||||
|
(require 's)
|
||||||
|
(require 'alert)
|
||||||
|
(require 'dom)
|
||||||
|
(require 'shr)
|
||||||
|
|
||||||
|
;; WSL-related functions and constants
|
||||||
|
;; In the words of WSL developers, there is no official way of testing for WSL
|
||||||
|
;; but they said at the same time that either "wsl" or "microsoft" should always
|
||||||
|
;; be present in the kernel release string.
|
||||||
|
(defun alert-toast--check-wsl ()
|
||||||
|
"Check if running under Windows Subsystem for Linux."
|
||||||
|
(and (eq system-type 'gnu/linux)
|
||||||
|
(let ((kernel-release (shell-command-to-string "uname --kernel-release")))
|
||||||
|
(or (s-contains? "wsl" kernel-release t)
|
||||||
|
(s-contains? "microsoft" kernel-release t)))))
|
||||||
|
|
||||||
|
(defconst alert-toast--wsl (alert-toast--check-wsl))
|
||||||
|
(defconst alert-toast--appdir-text "[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::LocalApplicationData) | Join-Path -ChildPath Emacs-Toast\\Emacs.png")
|
||||||
|
|
||||||
|
(defun alert-toast--appdir ()
|
||||||
|
"Path to Windows user's data directory."
|
||||||
|
(with-temp-buffer
|
||||||
|
(let ((coding-system-for-read 'utf-8-dos))
|
||||||
|
(call-process-region alert-toast--appdir-text nil "powershell.exe" nil t nil "-noprofile" "-NonInteractive" "-WindowStyle" "Hidden" "-Command" "-"))
|
||||||
|
(s-chomp (buffer-string))))
|
||||||
|
|
||||||
|
(defun alert-toast--default-wsl-icon-path ()
|
||||||
|
"Path to Emacs icon in Windows user's data directory."
|
||||||
|
(with-temp-buffer
|
||||||
|
(call-process "wslpath" nil t nil (alert-toast--appdir))
|
||||||
|
(s-chomp (buffer-string))))
|
||||||
|
|
||||||
|
(defun alert-toast--init-wsl-icon ()
|
||||||
|
"Copy Emacs icon to a Windows-side directory."
|
||||||
|
(let ((icon-path (alert-toast--default-wsl-icon-path)))
|
||||||
|
(unless (f-exists? icon-path)
|
||||||
|
(make-directory (f-parent icon-path) t)
|
||||||
|
(f-copy (concat data-directory "images/icons/hicolor/128x128/apps/emacs.png")
|
||||||
|
icon-path))))
|
||||||
|
|
||||||
|
(defun alert-toast--icon-path (path)
|
||||||
|
"Convert icon PATH from WSL/Cygwin to Windows path if needed."
|
||||||
|
(cond
|
||||||
|
(alert-toast--wsl
|
||||||
|
(with-temp-buffer
|
||||||
|
(call-process "wslpath" nil t nil "-m" path)
|
||||||
|
(s-chomp (buffer-string))))
|
||||||
|
((eq system-type 'cygwin)
|
||||||
|
(with-temp-buffer
|
||||||
|
(call-process "cygpath.exe" nil t nil "-w" path)
|
||||||
|
(s-chomp (buffer-string))))
|
||||||
|
(t path)))
|
||||||
|
|
||||||
|
;; Default icon
|
||||||
|
(defvar alert-toast-default-icon
|
||||||
|
(if alert-toast--wsl
|
||||||
|
(alert-toast--default-wsl-icon-path)
|
||||||
|
(concat data-directory "images/icons/hicolor/128x128/apps/emacs.png"))
|
||||||
|
"Path to default icon for toast notifications.")
|
||||||
|
|
||||||
|
;; Common part -- script body, powershell quoting, priorities and main function
|
||||||
|
(defconst alert-toast--psquote-replacements
|
||||||
|
'(("'" . "''")))
|
||||||
|
|
||||||
|
(defcustom alert-toast-priorities
|
||||||
|
'((urgent . "[Windows.UI.Notifications.ToastNotificationPriority]::High")
|
||||||
|
(high . "[Windows.UI.Notifications.ToastNotificationPriority]::High")
|
||||||
|
(moderate . "[Windows.UI.Notifications.ToastNotificationPriority]::Default")
|
||||||
|
(normal . "[Windows.UI.Notifications.ToastNotificationPriority]::Default")
|
||||||
|
(low . "[Windows.UI.Notifications.ToastNotificationPriority]::Default")
|
||||||
|
(trivial . "[Windows.UI.Notifications.ToastNotificationPriority]::Default"))
|
||||||
|
"A mapping of alert severities onto Windows 10 toast priority values."
|
||||||
|
:type '(alist :key-type symbol :value-type string)
|
||||||
|
:group 'alert)
|
||||||
|
|
||||||
|
(defconst alert-toast--sounds
|
||||||
|
'((default . "ms-winsoundevent:Notification.Default")
|
||||||
|
(im . "ms-winsoundevent:Notification.IM")
|
||||||
|
(mail . "ms-winsoundevent:Notification.Mail")
|
||||||
|
(reminder . "ms-winsoundevent:Notification.Reminder")
|
||||||
|
(sms . "ms-winsoundevent:Notification.SMS"))
|
||||||
|
"Alist of available sounds.")
|
||||||
|
|
||||||
|
(defconst alert-toast--looping-sounds
|
||||||
|
(let ((looping-sounds '((call . "ms-winsoundevent:Notification.Looping.Call")
|
||||||
|
(alarm . "ms-winsoundevent:Notification.Looping.Alarm"))))
|
||||||
|
(dolist (i '(2 3 4 5 6 7 8 9 10) looping-sounds)
|
||||||
|
(setq looping-sounds
|
||||||
|
(cons `(,(intern (format "call%d" i)) . ,(format "ms-winsoundevent:Notification.Looping.Call%d" i))
|
||||||
|
looping-sounds))
|
||||||
|
(setq looping-sounds
|
||||||
|
(cons `(,(intern (format "alarm%d" i)) . ,(format "ms-winsoundevent:Notification.Looping.Alarm%d" i))
|
||||||
|
looping-sounds))))
|
||||||
|
"Alist of available looping sounds.")
|
||||||
|
|
||||||
|
(defvar alert-toast--psprocess nil
|
||||||
|
"Persistent powershell process emitting toast notifications.")
|
||||||
|
|
||||||
|
(defun alert-toast--coding-page ()
|
||||||
|
"Get powershell encoding."
|
||||||
|
(with-temp-buffer
|
||||||
|
(let ((coding-system-for-read 'utf-8-dos))
|
||||||
|
(call-process-region "[console]::InputEncoding.BodyName" nil "powershell.exe" nil t nil "-noprofile" "-NonInteractive" "-WindowStyle" "Hidden" "-Command" "-"))
|
||||||
|
(intern-soft (s-chomp (buffer-string)))))
|
||||||
|
|
||||||
|
(defun alert-toast--psprocess-init ()
|
||||||
|
"Initialize powershell process."
|
||||||
|
(setq alert-toast--psprocess
|
||||||
|
(make-process :name "powershell-toast"
|
||||||
|
:buffer "*powershell-toast*"
|
||||||
|
:command '("powershell.exe" "-noprofile" "-NoExit" "-NonInteractive" "-WindowStyle" "Hidden"
|
||||||
|
"-Command" "-")
|
||||||
|
:coding (if alert-toast--wsl 'utf-8 (alert-toast--coding-page))
|
||||||
|
:noquery t
|
||||||
|
:connection-type 'pipe))
|
||||||
|
(process-send-string alert-toast--psprocess "[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
|
||||||
|
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml, ContentType=WindowsRuntime] > $null\n"))
|
||||||
|
|
||||||
|
(defun alert-toast--psprocess-kill ()
|
||||||
|
"Kill powershell process (for debugging)."
|
||||||
|
(delete-process alert-toast--psprocess)
|
||||||
|
(setq alert-toast--psprocess nil))
|
||||||
|
|
||||||
|
(defun alert-toast--fill-template (title message icon-path &optional audio silent long loop)
|
||||||
|
"Create alert toast XML document.
|
||||||
|
|
||||||
|
Set title to TITLE, message body to MESSAGE and icon to the image at ICON-PATH.
|
||||||
|
ICON-PATH has to be a native Windows path, use `alert-toast--icon-path' for
|
||||||
|
Cygwin->native and WSL->native conversion.
|
||||||
|
|
||||||
|
AUDIO can be one of symbols defined in `alert-toast--sounds' or
|
||||||
|
`alert-toast--looping-sounds'. If SILENT is non-nil, the notification is muted.
|
||||||
|
If LONG is non-nil or one of the sounds in `alert-toast--looping-sounds' was
|
||||||
|
provided as AUDIO, then the notification will last for ~20 s; otherwise it lasts
|
||||||
|
for several seconds. Non-nil LOOP will loop the sound."
|
||||||
|
(let ((looping-sound (alist-get audio alert-toast--looping-sounds))
|
||||||
|
(dom
|
||||||
|
(dom-node
|
||||||
|
'toast nil
|
||||||
|
(dom-node
|
||||||
|
'visual nil
|
||||||
|
(dom-node
|
||||||
|
'binding
|
||||||
|
'((template . "ToastImageAndText02"))
|
||||||
|
(dom-node 'text '((id . "1")) title)
|
||||||
|
(dom-node 'text '((id . "2")) message)
|
||||||
|
(dom-node 'image `((id . "1")
|
||||||
|
(src . ,icon-path)
|
||||||
|
(placement . "appLogoOverride"))))))))
|
||||||
|
(when (or audio silent loop)
|
||||||
|
(dom-append-child
|
||||||
|
dom (dom-node 'audio `((src . ,(or looping-sound
|
||||||
|
(alist-get audio alert-toast--sounds)
|
||||||
|
(alist-get 'default alert-toast--sounds)))
|
||||||
|
(silent . ,(if silent "true" "false"))
|
||||||
|
(loop . ,(if (or loop looping-sound) "true" "false"))))))
|
||||||
|
(when (or long looping-sound)
|
||||||
|
(dom-set-attribute dom 'duration "long"))
|
||||||
|
(shr-dom-to-xml dom)))
|
||||||
|
|
||||||
|
(defun alert-toast--fill-shoulder (title message icon-path person payload)
|
||||||
|
"Create shoulder tap XML document.
|
||||||
|
|
||||||
|
PERSON is an email address given as 'mailto:login@domain.com' of a contact
|
||||||
|
previously added to My People. PAYLOAD is either remote http or local path to a
|
||||||
|
GIF or PNG image. Under WSL and Cygwin, local paths need to be converted to
|
||||||
|
native Windows paths with `alert-toast--icon-path'.
|
||||||
|
|
||||||
|
As a fallback, set title to TITLE, message body to MESSAGE and icon to the image
|
||||||
|
at ICON-PATH. ICON-PATH has to be a native Windows path, use
|
||||||
|
`alert-toast--icon-path' for Cygwin->native and WSL->native conversion."
|
||||||
|
(let ((dom
|
||||||
|
(dom-node 'toast
|
||||||
|
`((hint-people . ,person))
|
||||||
|
(dom-node 'visual nil
|
||||||
|
(dom-node 'binding '((template . "ToastGeneric"))
|
||||||
|
(dom-node 'text nil title)
|
||||||
|
(dom-node 'text nil message)
|
||||||
|
(dom-node 'image `((src . ,icon-path)
|
||||||
|
(placement . "appLogoOverride")
|
||||||
|
(hint-crop . "circle"))))
|
||||||
|
(dom-node 'binding '((template . "ToastGeneric")
|
||||||
|
(experienceType . "shoulderTap"))
|
||||||
|
(dom-node 'image `((src . ,payload))))))))
|
||||||
|
(shr-dom-to-xml dom)))
|
||||||
|
|
||||||
|
(defconst alert-toast--psscript-text "$Xml = New-Object Windows.Data.Xml.Dom.XmlDocument
|
||||||
|
$Xml.LoadXml('%s')
|
||||||
|
|
||||||
|
$Toast = [Windows.UI.Notifications.ToastNotification]::new($Xml)
|
||||||
|
$Toast.Tag = \"Emacs\"
|
||||||
|
$Toast.Group = \"Emacs\"
|
||||||
|
$Toast.Priority = %s
|
||||||
|
$Toast.ExpirationTime = [DateTimeOffset]::Now.AddSeconds(%f)
|
||||||
|
|
||||||
|
$Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier(\"Emacs\")
|
||||||
|
$Notifier.Show($Toast);\n"
|
||||||
|
"Template of Powershell script emitting regular toast notification.")
|
||||||
|
|
||||||
|
(defconst alert-toast--psscript-shoulder "$Xml = New-Object Windows.Data.Xml.Dom.XmlDocument
|
||||||
|
$Xml.LoadXml('%s')
|
||||||
|
|
||||||
|
$Toast = [Windows.UI.Notifications.ToastNotification]::new($Xml)
|
||||||
|
|
||||||
|
$Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Microsoft.People_8wekyb3d8bbwe!x4c7a3b7dy2188y46d4ya362y19ac5a5805e5x')
|
||||||
|
$Notifier.Show($Toast);\n"
|
||||||
|
"Template of Powershell script emitting shoulder tap.")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun alert-toast-notify (info)
|
||||||
|
"Send INFO using Windows 10 toast notification.
|
||||||
|
Handles :ICON, :SEVERITY, :PERSISTENT, :NEVER-PERSIST, :TITLE and
|
||||||
|
:MESSAGE keywords from INFO plist."
|
||||||
|
(let ((data-plist (plist-get info :data))
|
||||||
|
psscript)
|
||||||
|
(if (and (plist-get data-plist :shoulder-person) (plist-get data-plist :shoulder-payload))
|
||||||
|
(setq psscript (format alert-toast--psscript-shoulder
|
||||||
|
(s-replace-all alert-toast--psquote-replacements
|
||||||
|
(alert-toast--fill-shoulder
|
||||||
|
(plist-get info :title)
|
||||||
|
(plist-get info :message)
|
||||||
|
(alert-toast--icon-path
|
||||||
|
(or (plist-get info :icon)
|
||||||
|
alert-toast-default-icon))
|
||||||
|
(plist-get data-plist :shoulder-person)
|
||||||
|
(plist-get data-plist :shoulder-payload)))))
|
||||||
|
(setq psscript
|
||||||
|
(format alert-toast--psscript-text
|
||||||
|
(s-replace-all alert-toast--psquote-replacements
|
||||||
|
(alert-toast--fill-template
|
||||||
|
(plist-get info :title)
|
||||||
|
(plist-get info :message)
|
||||||
|
(alert-toast--icon-path (or (plist-get info :icon) alert-toast-default-icon))
|
||||||
|
(plist-get data-plist :audio)
|
||||||
|
(plist-get data-plist :silent)
|
||||||
|
(plist-get data-plist :long)
|
||||||
|
(plist-get data-plist :loop)))
|
||||||
|
(or (cdr (assq (plist-get info :severity) alert-toast-priorities))
|
||||||
|
(cdr (assq 'normal alert-toast-priorities)))
|
||||||
|
(if (and (plist-get info :persistent)
|
||||||
|
(not (plist-get info :never-persist)))
|
||||||
|
(* 60 60 24 7) ; a week
|
||||||
|
alert-fade-time))))
|
||||||
|
(unless alert-toast--psprocess
|
||||||
|
(alert-toast--psprocess-init))
|
||||||
|
(process-send-string alert-toast--psprocess psscript)))
|
||||||
|
|
||||||
|
(alert-define-style 'toast :title "Windows 10 toast notification"
|
||||||
|
:notifier #'alert-toast-notify)
|
||||||
|
|
||||||
|
(when alert-toast--wsl
|
||||||
|
(alert-toast--init-wsl-icon))
|
||||||
|
|
||||||
|
(provide 'alert-toast)
|
||||||
|
;;; alert-toast.el ends here
|
28
org/elpa/gntp-20141025.250/gntp-autoloads.el
Normal file
28
org/elpa/gntp-20141025.250/gntp-autoloads.el
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
;;; gntp-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (directory-file-name
|
||||||
|
(or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;### (autoloads nil "gntp" "gntp.el" (0 0 0 0))
|
||||||
|
;;; Generated autoloads from gntp.el
|
||||||
|
|
||||||
|
(autoload 'gntp-notify "gntp" "\
|
||||||
|
Send notification NAME with TITLE, TEXT, PRIORITY and ICON to SERVER:PORT.
|
||||||
|
PORT defaults to `gntp-server-port'
|
||||||
|
|
||||||
|
\(fn NAME TITLE TEXT SERVER &optional PORT PRIORITY ICON)" nil nil)
|
||||||
|
|
||||||
|
(register-definition-prefixes "gntp" '("gntp-"))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; coding: utf-8
|
||||||
|
;; End:
|
||||||
|
;;; gntp-autoloads.el ends here
|
2
org/elpa/gntp-20141025.250/gntp-pkg.el
Normal file
2
org/elpa/gntp-20141025.250/gntp-pkg.el
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
;;; Generated package description from gntp.el -*- no-byte-compile: t -*-
|
||||||
|
(define-package "gntp" "20141025.250" "Growl Notification Protocol for Emacs" 'nil :commit "767571135e2c0985944017dc59b0be79af222ef5" :authors '(("Engelke Eschner" . "tekai@gmx.li")) :maintainer '("Engelke Eschner" . "tekai@gmx.li"))
|
244
org/elpa/gntp-20141025.250/gntp.el
Normal file
244
org/elpa/gntp-20141025.250/gntp.el
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
;;; gntp.el --- Growl Notification Protocol for Emacs -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Author: Engelke Eschner <tekai@gmx.li>
|
||||||
|
;; Version: 0.1
|
||||||
|
;; Package-Version: 20141025.250
|
||||||
|
;; Package-Commit: 767571135e2c0985944017dc59b0be79af222ef5
|
||||||
|
;; Created: 2013-03-21
|
||||||
|
|
||||||
|
;; LICENSE
|
||||||
|
;; Copyright (c) 2013 Engelke Eschner
|
||||||
|
;; All rights reserved.
|
||||||
|
|
||||||
|
;; Redistribution and use in source and binary forms, with or without
|
||||||
|
;; modification, are permitted provided that the following conditions
|
||||||
|
;; are met:
|
||||||
|
;; * Redistributions of source code must retain the above copyright
|
||||||
|
;; notice, this list of conditions and the following disclaimer.
|
||||||
|
;; * Redistributions in binary form must reproduce the above
|
||||||
|
;; copyright notice, this list of conditions and the following
|
||||||
|
;; disclaimer in the documentation and/or other materials provided
|
||||||
|
;; with the distribution.
|
||||||
|
;; * Neither the name of the gntp.el nor the names of its
|
||||||
|
;; contributors may be used to endorse or promote products derived
|
||||||
|
;; from this software without specific prior written permission.
|
||||||
|
|
||||||
|
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
|
||||||
|
;; HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
;; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
;; OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;; This package implements the Growl Notification Protocol GNTP
|
||||||
|
;; described at http://www.growlforwindows.com/gfw/help/gntp.aspx
|
||||||
|
;; It is incomplete as it only lets you send but not receive
|
||||||
|
;; notifications.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defgroup gntp nil
|
||||||
|
"GNTP, send/register growl notifications via GNTP from within emacs."
|
||||||
|
:group 'external)
|
||||||
|
|
||||||
|
(defcustom gntp-application-name "Emacs/gntp.el"
|
||||||
|
"Name of the application gntp registers itself."
|
||||||
|
:type '(string))
|
||||||
|
|
||||||
|
(defcustom gntp-application-icon nil
|
||||||
|
"Icon to display as the application icon.
|
||||||
|
Either a URL or a path to a file."
|
||||||
|
:type '(string))
|
||||||
|
|
||||||
|
(defcustom gntp-server "localhost"
|
||||||
|
"Default port of the server.
|
||||||
|
Standard says can't be changed, but port-forwarding etc."
|
||||||
|
:type '(string))
|
||||||
|
|
||||||
|
(defcustom gntp-server-port 23053
|
||||||
|
"Default port of the server.
|
||||||
|
Standard says can't be changed, but port-forwarding etc."
|
||||||
|
:type '(integer))
|
||||||
|
|
||||||
|
(defcustom gntp-register-alist nil
|
||||||
|
"Registration item list."
|
||||||
|
:type '(choice string (const nil)))
|
||||||
|
|
||||||
|
(defun gntp-register (&optional notifications server port)
|
||||||
|
(interactive)
|
||||||
|
"Register NOTIFICATIONS at SERVER:PORT.
|
||||||
|
PORT defaults to `gntp-server-port'."
|
||||||
|
(let ((message (gntp-build-message-register (if notifications notifications gntp-register-alist))))
|
||||||
|
(gntp-send message (if server server gntp-server) port)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun gntp-notify (name title text server &optional port priority icon)
|
||||||
|
"Send notification NAME with TITLE, TEXT, PRIORITY and ICON to SERVER:PORT.
|
||||||
|
PORT defaults to `gntp-server-port'"
|
||||||
|
(let ((message (gntp-build-message-notify name title text priority icon)))
|
||||||
|
(gntp-send message server port)))
|
||||||
|
|
||||||
|
(defun gntp-build-message-register (notifications)
|
||||||
|
"Build the message to register NOTIFICATIONS types."
|
||||||
|
(let ((lines (list "GNTP/1.0 REGISTER NONE"
|
||||||
|
(format "Application-Name: %s"
|
||||||
|
gntp-application-name)
|
||||||
|
(format "Notifications-Count: %d"
|
||||||
|
(length notifications))))
|
||||||
|
(icon-uri (gntp-app-icon-uri))
|
||||||
|
(icon-data (gntp-app-icon-data))
|
||||||
|
(icons (list)))
|
||||||
|
|
||||||
|
;; append icon uri
|
||||||
|
(when icon-uri
|
||||||
|
(nconc lines (list (format "Application-Icon: %s" icon-uri)))
|
||||||
|
;; and data when it exists
|
||||||
|
(when icon-data
|
||||||
|
(setq icons (cons icon-data icons))))
|
||||||
|
|
||||||
|
(dolist (notice notifications)
|
||||||
|
;; "For each notification being registered:
|
||||||
|
;; Each notification being registered should be seperated by a
|
||||||
|
;; blank line, including the first notification
|
||||||
|
(nconc lines (cons "" (gntp-notification-lines notice)))
|
||||||
|
;; c
|
||||||
|
(let ((icon (gntp-notice-icon-data notice)))
|
||||||
|
(when icon
|
||||||
|
(nconc icons (list "" icon)))))
|
||||||
|
|
||||||
|
;; icon data must come last
|
||||||
|
(when icons
|
||||||
|
(nconc lines (cons "" icons)))
|
||||||
|
|
||||||
|
(mapconcat 'identity (remove nil lines) "\r\n")))
|
||||||
|
|
||||||
|
(defun gntp-notification-lines (notice)
|
||||||
|
"Transform NOTICE into a list of strings."
|
||||||
|
(let ((display-name (gntp-notice-get notice :display))
|
||||||
|
(enabled (gntp-notice-get notice :enabled))
|
||||||
|
(icon-uri (gntp-notice-icon-uri notice)))
|
||||||
|
(list
|
||||||
|
;; Required - The name (type) of the notification being registered
|
||||||
|
(concat "Notification-Name: " (gntp-notice-name notice))
|
||||||
|
;; Optional - The name of the notification that is displayed to
|
||||||
|
;; the user (defaults to the same value as Notification-Name)
|
||||||
|
(when display-name
|
||||||
|
(concat "Notification-Display-Name: " display-name))
|
||||||
|
;; Optional - Indicates if the notification should be enabled by
|
||||||
|
;; default (defaults to False)
|
||||||
|
(when enabled
|
||||||
|
"Notification-Enabled: True")
|
||||||
|
;; Optional - The default icon to use for notifications of this type
|
||||||
|
(when icon-uri
|
||||||
|
(concat "Notification-Icon: " icon-uri)))))
|
||||||
|
|
||||||
|
(defun gntp-build-message-notify (name title text &optional priority icon)
|
||||||
|
"Build a message of type NAME with TITLE and TEXT."
|
||||||
|
|
||||||
|
(format
|
||||||
|
"GNTP/1.0 NOTIFY NONE\r\n\
|
||||||
|
Application-Name: %s\r\n\
|
||||||
|
Notification-Name: %s\r\n\
|
||||||
|
Notification-Title: %s\r\n\
|
||||||
|
Notification-Text: %s\r\n\
|
||||||
|
Notification-Priority: %s\r\n\
|
||||||
|
Notification-Icon: %s\r\n\
|
||||||
|
\r\n"
|
||||||
|
gntp-application-name
|
||||||
|
(if (symbolp name) (symbol-name name) name)
|
||||||
|
title
|
||||||
|
;; no CRLF in the text to avoid accidentel msg end
|
||||||
|
(replace-regexp-in-string "\r\n" "\n" text)
|
||||||
|
(if priority priority "0")
|
||||||
|
(if icon (gntp-icon-uri icon) "")))
|
||||||
|
|
||||||
|
;; notice
|
||||||
|
;;(list name ; everthing else is optional
|
||||||
|
;; :display "name to display"
|
||||||
|
;; :enabled nil
|
||||||
|
;; :icon "url or file")
|
||||||
|
|
||||||
|
|
||||||
|
(defun gntp-notice-icon-uri (notice)
|
||||||
|
"Get the icon URI from NOTICE."
|
||||||
|
(gntp-icon-uri (gntp-notice-get notice :icon)))
|
||||||
|
|
||||||
|
(defun gntp-notice-icon-data (notice)
|
||||||
|
"Get icon data from NOTICE."
|
||||||
|
(gntp-icon-data (gntp-notice-get notice :icon)))
|
||||||
|
|
||||||
|
(defun gntp-app-icon-uri ()
|
||||||
|
"Return the value to be used in the Application-Icon header."
|
||||||
|
(gntp-icon-uri gntp-application-icon))
|
||||||
|
|
||||||
|
(defun gntp-app-icon-data ()
|
||||||
|
"Return the value to be used in the Application-Icon header."
|
||||||
|
(gntp-icon-data gntp-application-icon))
|
||||||
|
|
||||||
|
(defun gntp-icon-uri (icon)
|
||||||
|
"Get the URI of ICON."
|
||||||
|
(when icon
|
||||||
|
(cond ((string-equal (substring icon 0 7) "http://") icon)
|
||||||
|
((and (file-exists-p icon) (file-readable-p icon))
|
||||||
|
(concat "x-growl-resource://" (md5 icon))))))
|
||||||
|
|
||||||
|
(defun gntp-icon-data (icon)
|
||||||
|
"Get the URI of ICON."
|
||||||
|
(when (and icon (not (string-equal (substring icon 0 7) "http://"))
|
||||||
|
(file-exists-p icon) (file-readable-p icon))
|
||||||
|
(let ((id (md5 icon))
|
||||||
|
(data (gntp-file-string icon)))
|
||||||
|
(format "Identifier: %s\r\nLength: %d\r\n\r\n%s"
|
||||||
|
id (length data) data))))
|
||||||
|
|
||||||
|
(defun gntp-notice-name (notice)
|
||||||
|
"Get the name of NOTICE. The name must be either a symbol or string."
|
||||||
|
(let ((name (car notice)))
|
||||||
|
(if (symbolp name)
|
||||||
|
(symbol-name name)
|
||||||
|
name)))
|
||||||
|
|
||||||
|
(defun gntp-notice-get (notice property)
|
||||||
|
"Get PROPERTY from NOTICE."
|
||||||
|
(plist-get (cdr notice) property))
|
||||||
|
|
||||||
|
(defun gntp-send (message server &optional port)
|
||||||
|
"Send MESSAGE to SERVER:PORT. PORT defaults to `gntp-server-port'."
|
||||||
|
(let ((proc (make-network-process
|
||||||
|
:name "gntp"
|
||||||
|
:host server
|
||||||
|
:server nil
|
||||||
|
:service (if port port gntp-server-port)
|
||||||
|
;;:sentinel 'gntp-sentinel
|
||||||
|
:filter 'gntp-filter)))
|
||||||
|
;; hmm one CRLF too much?
|
||||||
|
(process-send-string proc (concat message "\r\n\r\n\r\n"))))
|
||||||
|
|
||||||
|
(defun gntp-filter (proc string)
|
||||||
|
"Filter for PROC started by `gntp-send'.
|
||||||
|
Argument STRING reply from the server."
|
||||||
|
(when (string-equal "GNTP/1.0 -ERROR" (substring string 0 15))
|
||||||
|
(error "GNTP: Something went wrong take a look at the reply:\n %s"
|
||||||
|
string)))
|
||||||
|
|
||||||
|
;; (defun gntp-sentinel (proc msg)
|
||||||
|
;; (when (string= msg "connection broken by remote peer\n")
|
||||||
|
;; (message (format "client %s has quit" proc))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun gntp-file-string (file)
|
||||||
|
"Read the contents of a FILE and return as a string."
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents-literally file)
|
||||||
|
(buffer-string)))
|
||||||
|
|
||||||
|
(provide 'gntp)
|
||||||
|
|
||||||
|
;;; gntp.el ends here
|
33
org/elpa/log4e-20211019.948/log4e-autoloads.el
Normal file
33
org/elpa/log4e-20211019.948/log4e-autoloads.el
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
;;; log4e-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (directory-file-name
|
||||||
|
(or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;### (autoloads nil "log4e" "log4e.el" (0 0 0 0))
|
||||||
|
;;; Generated autoloads from log4e.el
|
||||||
|
|
||||||
|
(autoload 'log4e-mode "log4e" "\
|
||||||
|
Major mode for browsing a buffer made by log4e.
|
||||||
|
|
||||||
|
\\<log4e-mode-map>
|
||||||
|
\\{log4e-mode-map}
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'log4e:insert-start-log-quickly "log4e" "\
|
||||||
|
Insert logging statment for trace level log at start of current function/macro." t nil)
|
||||||
|
|
||||||
|
(register-definition-prefixes "log4e" '("log4e"))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; coding: utf-8
|
||||||
|
;; End:
|
||||||
|
;;; log4e-autoloads.el ends here
|
2
org/elpa/log4e-20211019.948/log4e-pkg.el
Normal file
2
org/elpa/log4e-20211019.948/log4e-pkg.el
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
;;; Generated package description from log4e.el -*- no-byte-compile: t -*-
|
||||||
|
(define-package "log4e" "20211019.948" "provide logging framework for elisp" 'nil :commit "737d275eac28dbdfb0b26d28e99da148bfce9d16" :authors '(("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) :maintainer '("Hiroaki Otsu" . "ootsuhiroaki@gmail.com") :keywords '("log") :url "https://github.com/aki2o/log4e")
|
592
org/elpa/log4e-20211019.948/log4e.el
Normal file
592
org/elpa/log4e-20211019.948/log4e.el
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
;;; log4e.el --- provide logging framework for elisp
|
||||||
|
|
||||||
|
;; Copyright (C) 2013 Hiroaki Otsu
|
||||||
|
|
||||||
|
;; Author: Hiroaki Otsu <ootsuhiroaki@gmail.com>
|
||||||
|
;; Keywords: log
|
||||||
|
;; Package-Version: 20211019.948
|
||||||
|
;; Package-Commit: 737d275eac28dbdfb0b26d28e99da148bfce9d16
|
||||||
|
;; URL: https://github.com/aki2o/log4e
|
||||||
|
;; Version: 0.3.3
|
||||||
|
|
||||||
|
;; 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 file 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; This extension provides logging framework for elisp.
|
||||||
|
|
||||||
|
;;; Dependency:
|
||||||
|
;;
|
||||||
|
;; Nothing.
|
||||||
|
|
||||||
|
;;; Installation:
|
||||||
|
;;
|
||||||
|
;; Put this to your load-path.
|
||||||
|
;; And put the following lines in your elisp file.
|
||||||
|
;;
|
||||||
|
;; (require 'log4e)
|
||||||
|
|
||||||
|
;;; Configuration:
|
||||||
|
;;
|
||||||
|
;; See <https://github.com/aki2o/log4e/blob/master/README.md>
|
||||||
|
;; Otherwise, eval following sexp.
|
||||||
|
;; (describe-function 'log4e:deflogger)
|
||||||
|
|
||||||
|
;;; API:
|
||||||
|
;;
|
||||||
|
;; [EVAL] (autodoc-document-lisp-buffer :type 'command :prefix "log4e:" :docstring t)
|
||||||
|
;; `log4e:next-log'
|
||||||
|
;; Move to start of next log on log4e-mode.
|
||||||
|
;; `log4e:previous-log'
|
||||||
|
;; Move to start of previous log on log4e-mode.
|
||||||
|
;; `log4e:insert-start-log-quickly'
|
||||||
|
;; Insert logging statment for trace level log at start of current function/macro.
|
||||||
|
;;
|
||||||
|
;; *** END auto-documentation
|
||||||
|
;;
|
||||||
|
;; For detail, see <https://github.com/aki2o/log4e/blob/master/README.md>
|
||||||
|
;;
|
||||||
|
;; [Note] Other than listed above, Those specifications may be changed without notice.
|
||||||
|
|
||||||
|
;;; Tested On:
|
||||||
|
;;
|
||||||
|
;; - Emacs ... GNU Emacs 23.3.1 (i386-mingw-nt5.1.2600) of 2011-08-15 on GNUPACK
|
||||||
|
|
||||||
|
|
||||||
|
;; Enjoy!!!
|
||||||
|
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(eval-when-compile (require 'cl-lib))
|
||||||
|
(require 'rx)
|
||||||
|
|
||||||
|
|
||||||
|
(defconst log4e-log-level-alist '((fatal . 6)
|
||||||
|
(error . 5)
|
||||||
|
(warn . 4)
|
||||||
|
(info . 3)
|
||||||
|
(debug . 2)
|
||||||
|
(trace . 1))
|
||||||
|
"Alist of log level value.")
|
||||||
|
|
||||||
|
(defconst log4e-default-logging-function-name-alist '((fatal . "log-fatal")
|
||||||
|
(error . "log-error")
|
||||||
|
(warn . "log-warn")
|
||||||
|
(info . "log-info")
|
||||||
|
(debug . "log-debug")
|
||||||
|
(trace . "log-trace"))
|
||||||
|
"Alist of logging function name at default.")
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro log4e--def-symmaker (symnm)
|
||||||
|
`(progn
|
||||||
|
(defsubst ,(intern (concat "log4e--make-symbol-" symnm)) (prefix)
|
||||||
|
(intern (concat ,(format "log4e--%s-" symnm) prefix)))))
|
||||||
|
|
||||||
|
(log4e--def-symmaker "log-buffer")
|
||||||
|
(log4e--def-symmaker "msg-buffer")
|
||||||
|
(log4e--def-symmaker "log-template")
|
||||||
|
(log4e--def-symmaker "time-template")
|
||||||
|
(log4e--def-symmaker "min-level")
|
||||||
|
(log4e--def-symmaker "max-level")
|
||||||
|
(log4e--def-symmaker "toggle-logging")
|
||||||
|
(log4e--def-symmaker "toggle-debugging")
|
||||||
|
(log4e--def-symmaker "buffer-coding-system")
|
||||||
|
(log4e--def-symmaker "author-mail-address")
|
||||||
|
|
||||||
|
(defmacro log4e--def-level-logger (prefix suffix level)
|
||||||
|
(let ((argform (if suffix
|
||||||
|
'(msg &rest msgargs)
|
||||||
|
'(level msg &rest msgargs)))
|
||||||
|
(buff (log4e--make-symbol-log-buffer prefix))
|
||||||
|
(msgbuff (log4e--make-symbol-msg-buffer prefix))
|
||||||
|
(codsys (log4e--make-symbol-buffer-coding-system prefix))
|
||||||
|
(logtmpl (log4e--make-symbol-log-template prefix))
|
||||||
|
(timetmpl (log4e--make-symbol-time-template prefix))
|
||||||
|
(minlvl (log4e--make-symbol-min-level prefix))
|
||||||
|
(maxlvl (log4e--make-symbol-max-level prefix))
|
||||||
|
(logging-p (log4e--make-symbol-toggle-logging prefix)))
|
||||||
|
`(progn
|
||||||
|
|
||||||
|
;; Define logging function
|
||||||
|
(defun ,(intern (concat prefix "--" (or suffix "log"))) ,argform
|
||||||
|
,(format "Do logging for %s level log.
|
||||||
|
%sMSG/MSGARGS are passed to `format'."
|
||||||
|
(if suffix level "any")
|
||||||
|
(if suffix "" "LEVEL is symbol as a log level in '(trace debug info warn error fatal).\n"))
|
||||||
|
(let ((log4e--current-msg-buffer ,msgbuff))
|
||||||
|
(apply 'log4e--logging ,buff ,codsys ,logtmpl ,timetmpl ,minlvl ,maxlvl ,logging-p ,(if suffix level 'level) msg msgargs)))
|
||||||
|
|
||||||
|
;; Define logging macro
|
||||||
|
(defmacro ,(intern (concat prefix "--" (or suffix "log") "*")) ,argform
|
||||||
|
,(format "Do logging for %s level log.
|
||||||
|
%sMSG/MSGARGS are passed to `format'.
|
||||||
|
Evaluation of MSGARGS is invoked only if %s level log should be printed."
|
||||||
|
(if suffix level "any")
|
||||||
|
(if suffix "" "LEVEL is symbol as a log level in '(trace debug info warn error fatal).\n")
|
||||||
|
(if suffix level "the"))
|
||||||
|
(let (,@(if suffix (list `(level ',level)) '())
|
||||||
|
(buff (log4e--make-symbol-log-buffer ,prefix))
|
||||||
|
(msgbuff (log4e--make-symbol-msg-buffer ,prefix))
|
||||||
|
(codsys (log4e--make-symbol-buffer-coding-system ,prefix))
|
||||||
|
(logtmpl (log4e--make-symbol-log-template ,prefix))
|
||||||
|
(timetmpl (log4e--make-symbol-time-template ,prefix))
|
||||||
|
(minlvl (log4e--make-symbol-min-level ,prefix))
|
||||||
|
(maxlvl (log4e--make-symbol-max-level ,prefix))
|
||||||
|
(logging-p (log4e--make-symbol-toggle-logging ,prefix)))
|
||||||
|
`(let ((log4e--current-msg-buffer ,msgbuff))
|
||||||
|
(when (and ,logging-p
|
||||||
|
(log4e--logging-level-p ,minlvl ,maxlvl ,level))
|
||||||
|
(log4e--logging ,buff ,codsys ,logtmpl ,timetmpl ,minlvl ,maxlvl ,logging-p ,level ,msg ,@msgargs)))))
|
||||||
|
|
||||||
|
)))
|
||||||
|
|
||||||
|
(defsubst log4e--logging-level-p (minlevel maxlevel currlevel)
|
||||||
|
(let ((minlvlvalue (or (assoc-default minlevel log4e-log-level-alist)
|
||||||
|
1))
|
||||||
|
(maxlvlvalue (or (assoc-default maxlevel log4e-log-level-alist)
|
||||||
|
6))
|
||||||
|
(currlvlvalue (or (assoc-default currlevel log4e-log-level-alist)
|
||||||
|
0)))
|
||||||
|
(and (>= currlvlvalue minlvlvalue)
|
||||||
|
(<= currlvlvalue maxlvlvalue))))
|
||||||
|
|
||||||
|
(defsubst log4e--get-or-create-log-buffer (buffnm &optional codesys)
|
||||||
|
(or (get-buffer buffnm)
|
||||||
|
(let ((buff (get-buffer-create buffnm)))
|
||||||
|
(with-current-buffer buff
|
||||||
|
(log4e-mode)
|
||||||
|
(when codesys
|
||||||
|
(setq buffer-file-coding-system codesys)))
|
||||||
|
buff)))
|
||||||
|
|
||||||
|
(defvar log4e--regexp-msg-format
|
||||||
|
(rx-to-string `(and "%"
|
||||||
|
(* (any "+#-0")) ; flags
|
||||||
|
(* (any "0-9")) ; width
|
||||||
|
(? "." (+ (any "0-9"))) ; precision
|
||||||
|
(any "a-zA-Z"))))
|
||||||
|
|
||||||
|
(defsubst log4e--insert-log (logtmpl timetmpl level msg msgargs propertize-p)
|
||||||
|
(let ((timetext (format-time-string timetmpl))
|
||||||
|
(lvltext (format "%-05s" (upcase (symbol-name level))))
|
||||||
|
(buffer-read-only nil))
|
||||||
|
(when propertize-p
|
||||||
|
(put-text-property 0 (length timetext) 'face 'font-lock-doc-face timetext)
|
||||||
|
(put-text-property 0 (length lvltext) 'face 'font-lock-keyword-face lvltext))
|
||||||
|
(let* ((logtext logtmpl)
|
||||||
|
(logtext (replace-regexp-in-string "%t" timetext logtext))
|
||||||
|
(logtext (replace-regexp-in-string "%l" lvltext logtext))
|
||||||
|
(logtext (replace-regexp-in-string "%m" msg logtext))
|
||||||
|
(begin (point)))
|
||||||
|
(insert logtext "\n")
|
||||||
|
(when propertize-p
|
||||||
|
(put-text-property begin (+ begin 1) 'log4e--level level))
|
||||||
|
(cl-loop initially (goto-char begin)
|
||||||
|
while (and msgargs
|
||||||
|
(re-search-forward log4e--regexp-msg-format nil t))
|
||||||
|
do (let* ((currtype (match-string-no-properties 0))
|
||||||
|
(currarg (pop msgargs))
|
||||||
|
(failfmt nil)
|
||||||
|
(currtext (condition-case e
|
||||||
|
(format currtype currarg)
|
||||||
|
(error (setq failfmt t)
|
||||||
|
(format "=%s=" (error-message-string e))))))
|
||||||
|
(save-match-data
|
||||||
|
(when propertize-p
|
||||||
|
(ignore-errors
|
||||||
|
(cond (failfmt (put-text-property 0 (length currtext) 'face 'font-lock-warning-face currtext))
|
||||||
|
(t (put-text-property 0 (length currtext) 'face 'font-lock-string-face currtext))))))
|
||||||
|
(replace-match currtext t t)))
|
||||||
|
(goto-char begin))))
|
||||||
|
|
||||||
|
(defvar log4e--current-msg-buffer nil)
|
||||||
|
|
||||||
|
;; We needs this signature be stay for other compiled plugins using old version
|
||||||
|
(defun log4e--logging (buffnm codsys logtmpl timetmpl minlevel maxlevel logging-p level msg &rest msgargs)
|
||||||
|
(when (and logging-p
|
||||||
|
(log4e--logging-level-p minlevel maxlevel level))
|
||||||
|
(save-match-data
|
||||||
|
(with-current-buffer (log4e--get-or-create-log-buffer buffnm codsys)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(let* ((buffer-read-only nil)
|
||||||
|
(begin (point))
|
||||||
|
(currlog (progn
|
||||||
|
(log4e--insert-log logtmpl timetmpl level msg msgargs t)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(buffer-substring-no-properties begin (point))))
|
||||||
|
(msgbuf (or (when (and log4e--current-msg-buffer
|
||||||
|
(not (eq log4e--current-msg-buffer t)))
|
||||||
|
(ignore-errors (get-buffer log4e--current-msg-buffer)))
|
||||||
|
log4e--current-msg-buffer)))
|
||||||
|
(when msgbuf
|
||||||
|
(let ((standard-output (if (buffer-live-p msgbuf)
|
||||||
|
msgbuf
|
||||||
|
standard-output)))
|
||||||
|
(princ currlog))))
|
||||||
|
nil))))
|
||||||
|
|
||||||
|
(defun log4e--get-current-log-line-level ()
|
||||||
|
(save-excursion
|
||||||
|
(beginning-of-line)
|
||||||
|
(get-text-property (point) 'log4e--level)))
|
||||||
|
|
||||||
|
;; We needs this signature be stay for other plugins compiled with this old version
|
||||||
|
(defun log4e--clear-log (buffnm)
|
||||||
|
(with-current-buffer (log4e--get-or-create-log-buffer buffnm)
|
||||||
|
(setq buffer-read-only nil)
|
||||||
|
(erase-buffer)))
|
||||||
|
|
||||||
|
;; We needs this signature be stay for other plugins compiled with this old version
|
||||||
|
(defun log4e--open-log (buffnm)
|
||||||
|
(let* ((buff (get-buffer buffnm)))
|
||||||
|
(if (not (buffer-live-p buff))
|
||||||
|
(message "[Log4E] Not exist log buffer.")
|
||||||
|
(with-current-buffer buff
|
||||||
|
(setq buffer-read-only t))
|
||||||
|
(pop-to-buffer buff))))
|
||||||
|
|
||||||
|
;; We needs this signature be stay for other plugins compiled with this old version
|
||||||
|
(defun log4e--open-log-if-debug (buffnm dbg)
|
||||||
|
(when dbg
|
||||||
|
(log4e--open-log buffnm)))
|
||||||
|
|
||||||
|
;; (defun log4e--send-report-if-not-debug (buffnm dbg addr prefix)
|
||||||
|
;; (let* ((buff (get-buffer buffnm)))
|
||||||
|
;; (when (and (not dbg)
|
||||||
|
;; (stringp addr)
|
||||||
|
;; (buffer-live-p buff))
|
||||||
|
;; (reporter-submit-bug-report addr prefix nil nil nil nil))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro log4e:deflogger (prefix msgtmpl timetmpl &optional log-function-name-custom-alist)
|
||||||
|
"Define the functions of logging for your elisp.
|
||||||
|
|
||||||
|
Specification:
|
||||||
|
After eval this, you can use the functions for supporting about logging. They are the following ...
|
||||||
|
- do logging for each log level. Log level are trace, debug, info, warn, error and fatal.
|
||||||
|
- set max and min log level.
|
||||||
|
- switch logging.
|
||||||
|
- switch debugging.
|
||||||
|
- open and clear log buffer.
|
||||||
|
- send bug report for you.
|
||||||
|
For details, see Functions section.
|
||||||
|
|
||||||
|
Argument:
|
||||||
|
- PREFIX is string as your elisp prefix.
|
||||||
|
- MSGTMPL is string as format of log. The following words has a special meaning.
|
||||||
|
- %t ... Replaced with time string. About it, see TIMETMPL argument.
|
||||||
|
- %l ... Replaced with log level. They are 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'.
|
||||||
|
- %m ... Replaced with log message that passed by you.
|
||||||
|
- TIMETMPL is string as format of time. This value is passed to `format-time-string'.
|
||||||
|
- LOG-FUNCTION-NAME-CUSTOM-ALIST is alist as the function name of logging.
|
||||||
|
- If this value is nil, define the following functions.
|
||||||
|
yourprefix--log-trace
|
||||||
|
yourprefix--log-debug
|
||||||
|
...
|
||||||
|
yourprefix--log-fatal
|
||||||
|
- If you want to custom the name of them, give like the following value.
|
||||||
|
'((fatal . \"fatal\")
|
||||||
|
(error . \"error\")
|
||||||
|
(warn . \"warn\")
|
||||||
|
(info . \"info\")
|
||||||
|
(debug . \"debug\")
|
||||||
|
(trace . \"trace\"))
|
||||||
|
Then, define the following functions.
|
||||||
|
yourprefix--trace
|
||||||
|
yourprefix--debug
|
||||||
|
...
|
||||||
|
yourprefix--fatal
|
||||||
|
|
||||||
|
Functions:
|
||||||
|
List all functions defined below. PREFIX is your prefix.
|
||||||
|
- PREFIX--log-fatal ... #1
|
||||||
|
- PREFIX--log-error ... #1
|
||||||
|
- PREFIX--log-warn ... #1
|
||||||
|
- PREFIX--log-info ... #1
|
||||||
|
- PREFIX--log-debug ... #1
|
||||||
|
- PREFIX--log-trace ... #1
|
||||||
|
- PREFIX--log-fatal* ... #2
|
||||||
|
- PREFIX--log-error* ... #2
|
||||||
|
- PREFIX--log-warn* ... #2
|
||||||
|
- PREFIX--log-info* ... #2
|
||||||
|
- PREFIX--log-debug* ... #2
|
||||||
|
- PREFIX--log-trace* ... #2
|
||||||
|
- PREFIX--log
|
||||||
|
- PREFIX--log-set-level
|
||||||
|
- PREFIX--log-enable-logging ... #3
|
||||||
|
- PREFIX--log-disable-logging ... #3
|
||||||
|
- PREFIX--log-enable-messaging ... #3
|
||||||
|
- PREFIX--log-disable-messaging ... #3
|
||||||
|
- PREFIX--log-enable-debugging ... #3
|
||||||
|
- PREFIX--log-disable-debugging ... #3
|
||||||
|
- PREFIX--log-debugging-p
|
||||||
|
- PREFIX--log-set-coding-system
|
||||||
|
- PREFIX--log-set-author-mail-address
|
||||||
|
- PREFIX--log-clear-log ... #3
|
||||||
|
- PREFIX--log-open-log ... #3
|
||||||
|
- PREFIX--log-open-log-if-debug
|
||||||
|
|
||||||
|
#1 : You can customize this name
|
||||||
|
#2 : Name is a #1 name + \"*\"
|
||||||
|
#3 : This is command
|
||||||
|
|
||||||
|
Example:
|
||||||
|
;; If you develop elisp that has prefix \"hoge\", write and eval the following sexp in your elisp file.
|
||||||
|
|
||||||
|
(require 'log4e)
|
||||||
|
(log4e:deflogger \"hoge\" \"%t [%l] %m\" \"%H:%M:%S\")
|
||||||
|
|
||||||
|
;; Eval the following
|
||||||
|
(hoge--log-enable-logging)
|
||||||
|
|
||||||
|
;; Then, write the following
|
||||||
|
|
||||||
|
(defun hoge-do-hoge (hoge)
|
||||||
|
(if (not (stringp hoge))
|
||||||
|
(hoge--log-fatal \"failed do hoge : hoge is '%s'\" hoge)
|
||||||
|
(hoge--log-debug \"start do hoge about '%s'\" hoge)
|
||||||
|
(message \"hoge!\")
|
||||||
|
(hoge--log-info \"done hoge about '%s'\" hoge)))
|
||||||
|
|
||||||
|
;; Eval the following
|
||||||
|
(hoge-do-hoge \"HOGEGE\")
|
||||||
|
|
||||||
|
;; Do M-x hoge--log-open-log
|
||||||
|
;; Open the buffer which name is \" *log4e-hoge*\". The buffer string is below
|
||||||
|
12:34:56 [INFO ] done hoge about 'HOGEGE'
|
||||||
|
|
||||||
|
;; Eval the following
|
||||||
|
(hoge--log-set-level 'trace)
|
||||||
|
(hoge-do-hoge \"FUGAGA\")
|
||||||
|
|
||||||
|
;; Do M-x hoge--log-open-log
|
||||||
|
;; Open the buffer. its string is below
|
||||||
|
12:34:56 [INFO ] done hoge about 'HOGEGE'
|
||||||
|
12:35:43 [DEBUG] start do hoge about 'FUGAGA'
|
||||||
|
12:35:43 [INFO ] done hoge about 'FUGAGA'
|
||||||
|
|
||||||
|
"
|
||||||
|
(declare (indent 0))
|
||||||
|
(if (or (not (stringp prefix)) (string= prefix "")
|
||||||
|
(not (stringp msgtmpl)) (string= msgtmpl "")
|
||||||
|
(not (stringp timetmpl)) (string= timetmpl ""))
|
||||||
|
(message "[LOG4E] invalid argument of deflogger")
|
||||||
|
(let* ((bufsym (log4e--make-symbol-log-buffer prefix))
|
||||||
|
(msgbufsym (log4e--make-symbol-msg-buffer prefix))
|
||||||
|
(logtmplsym (log4e--make-symbol-log-template prefix))
|
||||||
|
(timetmplsym (log4e--make-symbol-time-template prefix))
|
||||||
|
(minlvlsym (log4e--make-symbol-min-level prefix))
|
||||||
|
(maxlvlsym (log4e--make-symbol-max-level prefix))
|
||||||
|
(tglsym (log4e--make-symbol-toggle-logging prefix))
|
||||||
|
(dbgsym (log4e--make-symbol-toggle-debugging prefix))
|
||||||
|
(codsyssym (log4e--make-symbol-buffer-coding-system prefix))
|
||||||
|
(addrsym (log4e--make-symbol-author-mail-address prefix))
|
||||||
|
(funcnm-alist (cl-loop with custom-alist = (car (cdr log-function-name-custom-alist))
|
||||||
|
for lvl in '(fatal error warn info debug trace)
|
||||||
|
for lvlpair = (assq lvl custom-alist)
|
||||||
|
for fname = (or (cdr-safe lvlpair) "")
|
||||||
|
collect (or (if (string-match "\*" fname)
|
||||||
|
(progn
|
||||||
|
(message "[LOG4E] ignore %s level name in log-function-name-custom-alist. can't use '*' for the name." lvl)
|
||||||
|
nil)
|
||||||
|
lvlpair)
|
||||||
|
(assq lvl log4e-default-logging-function-name-alist)))))
|
||||||
|
`(progn
|
||||||
|
|
||||||
|
;; Define variable for prefix
|
||||||
|
(defvar ,bufsym (format " *log4e-%s*" ,prefix))
|
||||||
|
(defvar ,logtmplsym ,msgtmpl)
|
||||||
|
(defvar ,timetmplsym ,timetmpl)
|
||||||
|
(defvar ,minlvlsym 'info)
|
||||||
|
(defvar ,maxlvlsym 'fatal)
|
||||||
|
(defvar ,tglsym nil)
|
||||||
|
(defvar ,msgbufsym nil)
|
||||||
|
(defvar ,dbgsym nil)
|
||||||
|
(defvar ,codsyssym nil)
|
||||||
|
(defvar ,addrsym nil)
|
||||||
|
|
||||||
|
;; Define level set function
|
||||||
|
(defun ,(intern (concat prefix "--log-set-level")) (minlevel &optional maxlevel)
|
||||||
|
"Set range for doing logging.
|
||||||
|
|
||||||
|
MINLEVEL is symbol of lowest level for doing logging. its default is 'info.
|
||||||
|
MAXLEVEL is symbol of highest level for doing logging. its default is 'fatal."
|
||||||
|
(setq ,minlvlsym minlevel)
|
||||||
|
(setq ,maxlvlsym maxlevel))
|
||||||
|
|
||||||
|
;; Define logging toggle function
|
||||||
|
(defun ,(intern (concat prefix "--log-enable-logging")) ()
|
||||||
|
"Enable logging by logging functions."
|
||||||
|
(interactive)
|
||||||
|
(setq ,tglsym t))
|
||||||
|
(defun ,(intern (concat prefix "--log-disable-logging")) ()
|
||||||
|
"Disable logging by logging functions."
|
||||||
|
(interactive)
|
||||||
|
(setq ,tglsym nil))
|
||||||
|
|
||||||
|
;; Define messaging toggle function
|
||||||
|
(defun ,(intern (concat prefix "--log-enable-messaging")) (&optional buffer)
|
||||||
|
"Enable dump the log into other buffer by logging functions.
|
||||||
|
|
||||||
|
BUFFER is a buffer dumped log into. nil means *Messages* buffer."
|
||||||
|
(interactive)
|
||||||
|
(setq ,msgbufsym (or buffer t)))
|
||||||
|
(defun ,(intern (concat prefix "--log-disable-messaging")) ()
|
||||||
|
"Disable dump the log into other buffer by logging functions."
|
||||||
|
(interactive)
|
||||||
|
(setq ,msgbufsym nil))
|
||||||
|
|
||||||
|
;; Define debugging toggle function
|
||||||
|
(defun ,(intern (concat prefix "--log-enable-debugging")) ()
|
||||||
|
"Enable debugging and logging.
|
||||||
|
|
||||||
|
`PREFIX--log-debugging-p' will return t."
|
||||||
|
(interactive)
|
||||||
|
(setq ,tglsym t)
|
||||||
|
(setq ,dbgsym t))
|
||||||
|
(defun ,(intern (concat prefix "--log-disable-debugging")) ()
|
||||||
|
"Disable debugging.
|
||||||
|
|
||||||
|
`PREFIX--log-debugging-p' will return nil."
|
||||||
|
(interactive)
|
||||||
|
(setq ,dbgsym nil))
|
||||||
|
(defun ,(intern (concat prefix "--log-debugging-p")) ()
|
||||||
|
,dbgsym)
|
||||||
|
|
||||||
|
;; Define coding system set funtion
|
||||||
|
(defun ,(intern (concat prefix "--log-set-coding-system")) (coding-system)
|
||||||
|
"Set charset and linefeed of LOG-BUFFER.
|
||||||
|
|
||||||
|
CODING-SYSTEM is symbol for setting to `buffer-file-coding-system'.
|
||||||
|
LOG-BUFFER is a buffer which name is \" *log4e-PREFIX*\"."
|
||||||
|
(setq ,codsyssym coding-system))
|
||||||
|
|
||||||
|
;; ;; Define author mail set function
|
||||||
|
;; (defun ,(intern (concat prefix "--log-set-author-mail-address")) (before-atmark after-atmark)
|
||||||
|
;; "Set mail address of author for elisp that has PREFIX. This value is used SEND-REPORT.
|
||||||
|
|
||||||
|
;; BEFORE-ATMARK is string as part of mail address. If your address is \"hoge@example.co.jp\", it is \"hoge\".
|
||||||
|
;; AFTER-ATMARK is string as part of mail address. If your address is \"hoge@example.co.jp\", it is \"example.co.jp\".
|
||||||
|
;; SEND-REPORT is `PREFIX--log-send-report-if-not-debug'."
|
||||||
|
;; (setq ,addrsym (concat before-atmark "@" after-atmark)))
|
||||||
|
|
||||||
|
;; Define log buffer handle function
|
||||||
|
(defun ,(intern (concat prefix "--log-clear-log")) ()
|
||||||
|
"Clear buffer string of buffer which name is \" *log4e-PREFIX*\"."
|
||||||
|
(interactive)
|
||||||
|
(log4e--clear-log ,bufsym))
|
||||||
|
(defun ,(intern (concat prefix "--log-open-log")) ()
|
||||||
|
"Open buffer which name is \" *log4e-PREFIX*\"."
|
||||||
|
(interactive)
|
||||||
|
(log4e--open-log ,bufsym))
|
||||||
|
(defun ,(intern (concat prefix "--log-open-log-if-debug")) ()
|
||||||
|
"Open buffer which name is \" *log4e-PREFIX*\" if debugging is enabled."
|
||||||
|
(log4e--open-log-if-debug ,bufsym ,dbgsym))
|
||||||
|
|
||||||
|
;; ;; Define report send function
|
||||||
|
;; (defun ,(intern (concat prefix "--log-send-report-if-not-debug")) ()
|
||||||
|
;; "Send bug report to author if debugging is disabled.
|
||||||
|
|
||||||
|
;; The author mailaddress is set by `PREFIX--log-set-author-mail-address'.
|
||||||
|
;; About the way of sending bug report, see `reporter-submit-bug-report'."
|
||||||
|
;; (log4e--send-report-if-not-debug ,bufsym ,dbgsym ,addrsym ,prefix))
|
||||||
|
|
||||||
|
;; Define each level logging function
|
||||||
|
(log4e--def-level-logger ,prefix nil nil)
|
||||||
|
(log4e--def-level-logger ,prefix ,(assoc-default 'fatal funcnm-alist) 'fatal)
|
||||||
|
(log4e--def-level-logger ,prefix ,(assoc-default 'error funcnm-alist) 'error)
|
||||||
|
(log4e--def-level-logger ,prefix ,(assoc-default 'warn funcnm-alist) 'warn)
|
||||||
|
(log4e--def-level-logger ,prefix ,(assoc-default 'info funcnm-alist) 'info)
|
||||||
|
(log4e--def-level-logger ,prefix ,(assoc-default 'debug funcnm-alist) 'debug)
|
||||||
|
(log4e--def-level-logger ,prefix ,(assoc-default 'trace funcnm-alist) 'trace)
|
||||||
|
|
||||||
|
))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-derived-mode log4e-mode view-mode "Log4E"
|
||||||
|
"Major mode for browsing a buffer made by log4e.
|
||||||
|
|
||||||
|
\\<log4e-mode-map>
|
||||||
|
\\{log4e-mode-map}"
|
||||||
|
(define-key log4e-mode-map (kbd "J") 'log4e:next-log)
|
||||||
|
(define-key log4e-mode-map (kbd "K") 'log4e:previous-log))
|
||||||
|
|
||||||
|
(defun log4e:next-log ()
|
||||||
|
"Move to start of next log on log4e-mode."
|
||||||
|
(interactive)
|
||||||
|
(let* ((level))
|
||||||
|
(while (and (not level)
|
||||||
|
(< (point) (point-max)))
|
||||||
|
(forward-line 1)
|
||||||
|
(setq level (log4e--get-current-log-line-level)))
|
||||||
|
level))
|
||||||
|
|
||||||
|
(defun log4e:previous-log ()
|
||||||
|
"Move to start of previous log on log4e-mode."
|
||||||
|
(interactive)
|
||||||
|
(let* ((level))
|
||||||
|
(while (and (not level)
|
||||||
|
(> (point) (point-min)))
|
||||||
|
(forward-line -1)
|
||||||
|
(setq level (log4e--get-current-log-line-level)))
|
||||||
|
level))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun log4e:insert-start-log-quickly ()
|
||||||
|
"Insert logging statment for trace level log at start of current function/macro."
|
||||||
|
(interactive)
|
||||||
|
(let* ((fstartpt (when (re-search-backward "(\\(?:defun\\|defmacro\\|defsubst\\)\\*? +\\([^ ]+\\) +(\\([^)]*\\))" nil t)
|
||||||
|
(point)))
|
||||||
|
(fncnm (when fstartpt (match-string-no-properties 1)))
|
||||||
|
(argtext (when fstartpt (match-string-no-properties 2)))
|
||||||
|
(prefix (save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(cl-loop while (re-search-forward "(log4e:deflogger[ \n]+\"\\([^\"]+\\)\"" nil t)
|
||||||
|
for prefix = (match-string-no-properties 1)
|
||||||
|
for currface = (get-text-property (match-beginning 0) 'face)
|
||||||
|
if (not (eq currface 'font-lock-comment-face))
|
||||||
|
return prefix))))
|
||||||
|
(when (and fstartpt prefix)
|
||||||
|
(let* ((fncnm (replace-regexp-in-string (concat "\\`" prefix "[^a-zA-Z0-9]+") "" fncnm))
|
||||||
|
(fncnm (replace-regexp-in-string "-" " " fncnm))
|
||||||
|
(argtext (replace-regexp-in-string "\n" " " argtext))
|
||||||
|
(argtext (replace-regexp-in-string "^ +" "" argtext))
|
||||||
|
(argtext (replace-regexp-in-string " +$" "" argtext))
|
||||||
|
(args (split-string argtext " +"))
|
||||||
|
(args (cl-loop for arg in args
|
||||||
|
if (and (not (string= arg ""))
|
||||||
|
(not (string-match "\\`&" arg)))
|
||||||
|
collect arg))
|
||||||
|
(logtext (cl-loop with ret = (format "start %s." fncnm)
|
||||||
|
for arg in args
|
||||||
|
do (setq ret (concat ret " " arg "[%s]"))
|
||||||
|
finally return ret))
|
||||||
|
(sexpformat (cl-loop with ret = "(%s--log 'trace \"%s\""
|
||||||
|
for arg in args
|
||||||
|
do (setq ret (concat ret " %s"))
|
||||||
|
finally return (concat ret ")")))
|
||||||
|
(inserttext (apply 'format sexpformat prefix logtext args)))
|
||||||
|
(forward-char)
|
||||||
|
(forward-sexp 3)
|
||||||
|
(when (re-search-forward "\\=[ \n]+\"" nil t)
|
||||||
|
(forward-char -1)
|
||||||
|
(forward-sexp))
|
||||||
|
(newline-and-indent)
|
||||||
|
(insert inserttext)))))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'log4e)
|
||||||
|
;;; log4e.el ends here
|
22
org/elpa/org-alert-20220721.1721/org-alert-autoloads.el
Normal file
22
org/elpa/org-alert-20220721.1721/org-alert-autoloads.el
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
;;; org-alert-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (directory-file-name
|
||||||
|
(or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;### (autoloads nil "org-alert" "org-alert.el" (0 0 0 0))
|
||||||
|
;;; Generated autoloads from org-alert.el
|
||||||
|
|
||||||
|
(register-definition-prefixes "org-alert" '("org-alert-"))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; coding: utf-8
|
||||||
|
;; End:
|
||||||
|
;;; org-alert-autoloads.el ends here
|
2
org/elpa/org-alert-20220721.1721/org-alert-pkg.el
Normal file
2
org/elpa/org-alert-20220721.1721/org-alert-pkg.el
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
;;; Generated package description from org-alert.el -*- no-byte-compile: t -*-
|
||||||
|
(define-package "org-alert" "20220721.1721" "Notify org deadlines via notify-send" '((org "9.0") (alert "1.2")) :commit "f1801e061722843329b95409957c7dbd5cc223e9" :authors '(("Stephen Pegoraro" . "spegoraro@tutive.com")) :maintainer '("Stephen Pegoraro" . "spegoraro@tutive.com") :keywords '("org" "org-mode" "notify" "notifications" "calendar") :url "https://github.com/spegoraro/org-alert")
|
169
org/elpa/org-alert-20220721.1721/org-alert.el
Normal file
169
org/elpa/org-alert-20220721.1721/org-alert.el
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
;;; org-alert.el --- Notify org deadlines via notify-send
|
||||||
|
|
||||||
|
;; Copyright (C) 2015 Stephen Pegoraro
|
||||||
|
|
||||||
|
;; Author: Stephen Pegoraro <spegoraro@tutive.com>
|
||||||
|
;; Version: 0.2.0
|
||||||
|
;; Package-Version: 20220721.1721
|
||||||
|
;; Package-Commit: f1801e061722843329b95409957c7dbd5cc223e9
|
||||||
|
;; Package-Requires: ((org "9.0") (alert "1.2"))
|
||||||
|
;; Keywords: org, org-mode, notify, notifications, calendar
|
||||||
|
;; URL: https://github.com/spegoraro/org-alert
|
||||||
|
|
||||||
|
;; 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This package provides functions to display system notifications for
|
||||||
|
;; any org-mode deadlines that are due in your agenda. To perform a
|
||||||
|
;; one-shot check call (org-alert-deadlines). To enable repeated
|
||||||
|
;; checking call (org-alert-enable) and to disable call
|
||||||
|
;; (org-alert-disable). You can set the checking interval by changing
|
||||||
|
;; the org-alert-interval variable to the number of seconds you'd
|
||||||
|
;; like.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'alert)
|
||||||
|
(require 'org-agenda)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar org-alert-interval 300
|
||||||
|
"Interval in seconds to recheck and display deadlines.")
|
||||||
|
|
||||||
|
;; TODO look for a property of the agenda entry as suggested in
|
||||||
|
;; https://github.com/spegoraro/org-alert/issues/20
|
||||||
|
(defvar org-alert-notify-cutoff 10
|
||||||
|
"Time in minutes before a deadline a notification should be sent.")
|
||||||
|
|
||||||
|
(defvar org-alert-notify-after-event-cutoff nil
|
||||||
|
"Time in minutes after a deadline to stop sending notifications.
|
||||||
|
If nil, never stop sending notifications.")
|
||||||
|
|
||||||
|
(defvar org-alert-notification-title "*org*"
|
||||||
|
"Title to be sent with notify-send.")
|
||||||
|
|
||||||
|
(defvar org-alert-match-string
|
||||||
|
"SCHEDULED>=\"<today>\"+SCHEDULED<\"<tomorrow>\"|DEADLINE>=\"<today>\"+DEADLINE<\"<tomorrow>\""
|
||||||
|
"property/todo/tags match string to be passed to `org-map-entries'.")
|
||||||
|
|
||||||
|
(defvar org-alert-time-match-string
|
||||||
|
"\\(?:SCHEDULED\\|DEADLINE\\):.*<.*\\([0-9]\\{2\\}:[0-9]\\{2\\}\\).*>"
|
||||||
|
"regex to find times in an org subtree. The first capture group
|
||||||
|
is used to extract the time")
|
||||||
|
|
||||||
|
(defun org-alert--read-subtree ()
|
||||||
|
"Return the current subtree as a string. Adapted from
|
||||||
|
`org-copy-subtree` from org-mode."
|
||||||
|
(org-preserve-local-variables
|
||||||
|
(let (beg end folded (beg0 (point)))
|
||||||
|
(org-back-to-heading t)
|
||||||
|
(setq beg (point))
|
||||||
|
(skip-chars-forward " \t\r\n")
|
||||||
|
(save-match-data
|
||||||
|
(save-excursion (outline-end-of-heading)
|
||||||
|
(setq folded (org-invisible-p)))
|
||||||
|
(ignore-errors (org-forward-heading-same-level (1- n) t))
|
||||||
|
(org-end-of-subtree t t))
|
||||||
|
;; Include the end of an inlinetask
|
||||||
|
(when (and (featurep 'org-inlinetask)
|
||||||
|
(looking-at-p (concat (org-inlinetask-outline-regexp)
|
||||||
|
"END[ \t]*$")))
|
||||||
|
(end-of-line))
|
||||||
|
(setq end (point))
|
||||||
|
(goto-char beg0)
|
||||||
|
(when (> end beg)
|
||||||
|
(setq org-subtree-clip-folded folded)
|
||||||
|
(buffer-substring-no-properties beg end)))))
|
||||||
|
|
||||||
|
;; I think this is unnecessary now that we're using read-subtree
|
||||||
|
;; instead of copy-subtree
|
||||||
|
(defun org-alert--strip-text-properties (text)
|
||||||
|
"Strip all of the text properties from a copy of TEXT and
|
||||||
|
return the stripped copy"
|
||||||
|
(let ((text (substring text)))
|
||||||
|
(set-text-properties 0 (length text) nil text)
|
||||||
|
text))
|
||||||
|
|
||||||
|
(defun org-alert--grab-subtree ()
|
||||||
|
"Return the current org subtree as a string with the
|
||||||
|
text-properties stripped"
|
||||||
|
(let* ((subtree (org-alert--read-subtree))
|
||||||
|
(text (org-alert--strip-text-properties subtree)))
|
||||||
|
(apply #'concat
|
||||||
|
(cl-remove-if #'(lambda (s) (string= s ""))
|
||||||
|
(cdr (split-string text "\n"))))))
|
||||||
|
|
||||||
|
(defun org-alert--to-minute (hour minute)
|
||||||
|
"Convert HOUR and MINUTE to minutes"
|
||||||
|
(+ (* 60 hour) minute))
|
||||||
|
|
||||||
|
(defun org-alert--check-time (time &optional now)
|
||||||
|
"Check if TIME is less than `org-alert-notify-cutoff` from NOW. If
|
||||||
|
`org-alert-notify-after-event-cutoff` is set, also check that NOW
|
||||||
|
is less than `org-alert-notify-after-event-cutoff` past TIME."
|
||||||
|
(let* ((time (mapcar #'string-to-number (split-string time ":")))
|
||||||
|
(now (or now (decode-time (current-time))))
|
||||||
|
(now (org-alert--to-minute (decoded-time-hour now) (decoded-time-minute now)))
|
||||||
|
(then (org-alert--to-minute (car time) (cadr time)))
|
||||||
|
(time-until (- then now)))
|
||||||
|
(if org-alert-notify-after-event-cutoff
|
||||||
|
(and
|
||||||
|
(<= time-until org-alert-notify-cutoff)
|
||||||
|
;; negative time-until past events
|
||||||
|
(> time-until (- org-alert-notify-after-event-cutoff)))
|
||||||
|
(<= time-until org-alert-notify-cutoff))))
|
||||||
|
|
||||||
|
(defun org-alert--parse-entry ()
|
||||||
|
"Parse an entry from the org agenda and return a list of the
|
||||||
|
heading and the scheduled/deadline time"
|
||||||
|
(let ((head (org-alert--strip-text-properties (org-get-heading t t t t)))
|
||||||
|
(body (org-alert--grab-subtree)))
|
||||||
|
(string-match org-alert-time-match-string body)
|
||||||
|
(list head (match-string 1 body))))
|
||||||
|
|
||||||
|
(defun org-alert--dispatch ()
|
||||||
|
(let* ((entry (org-alert--parse-entry))
|
||||||
|
(head (car entry))
|
||||||
|
(time (cadr entry)))
|
||||||
|
(if time
|
||||||
|
(when (org-alert--check-time time)
|
||||||
|
(alert (concat time ": " head) :title org-alert-notification-title))
|
||||||
|
(alert head :title org-alert-notification-title))))
|
||||||
|
|
||||||
|
(defun org-alert-check ()
|
||||||
|
"Check for active, due deadlines and initiate notifications."
|
||||||
|
(interactive)
|
||||||
|
(org-map-entries 'org-alert--dispatch org-alert-match-string 'agenda
|
||||||
|
'(org-agenda-skip-entry-if 'todo
|
||||||
|
org-done-keywords-for-agenda))
|
||||||
|
t)
|
||||||
|
|
||||||
|
(defun org-alert-enable ()
|
||||||
|
"Enable the notification timer. Cancels existing timer if running."
|
||||||
|
(interactive)
|
||||||
|
(org-alert-disable)
|
||||||
|
(run-at-time 0 org-alert-interval 'org-alert-check))
|
||||||
|
|
||||||
|
(defun org-alert-disable ()
|
||||||
|
"Cancel the running notification timer."
|
||||||
|
(interactive)
|
||||||
|
(dolist (timer timer-list)
|
||||||
|
(if (eq (elt timer 5) 'org-alert-check)
|
||||||
|
(cancel-timer timer))))
|
||||||
|
|
||||||
|
(provide 'org-alert)
|
||||||
|
;;; org-alert.el ends here
|
15
org/init.el
15
org/init.el
|
@ -63,14 +63,24 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; additional packages
|
; additional packages
|
||||||
(add-to-list 'package-selected-packages
|
(add-to-list 'package-selected-packages
|
||||||
'(ox-hugo org-super-agenda org-alert)
|
'(ox-hugo org-super-agenda org-alert alert-toast alert)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; Load misc extensions
|
; Load misc extensions
|
||||||
(require 'org)
|
(require 'org)
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; org-alert - windows only
|
||||||
|
(when (eq system-type 'windows-nt)
|
||||||
(use-package org-alert)
|
(use-package org-alert)
|
||||||
|
(use-package alert-toast :after alert)
|
||||||
|
(setq alert-default-style 'toast)
|
||||||
|
(setq org-alert-interval 300
|
||||||
|
org-alert-notify-cutoff 15
|
||||||
|
org-alert-notify-after-event-cutoff 86400)
|
||||||
|
)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; Update/add auto file handling
|
; Update/add auto file handling
|
||||||
|
@ -214,4 +224,5 @@
|
||||||
;; Your init file should contain only one such instance.
|
;; Your init file should contain only one such instance.
|
||||||
;; If there is more than one, they won't work right.
|
;; If there is more than one, they won't work right.
|
||||||
'(custom-safe-themes
|
'(custom-safe-themes
|
||||||
'("dde643b0efb339c0de5645a2bc2e8b4176976d5298065b8e6ca45bc4ddf188b7" "bfc0b9c3de0382e452a878a1fb4726e1302bf9da20e69d6ec1cd1d5d82f61e3d" default)))
|
'("dde643b0efb339c0de5645a2bc2e8b4176976d5298065b8e6ca45bc4ddf188b7" "bfc0b9c3de0382e452a878a1fb4726e1302bf9da20e69d6ec1cd1d5d82f61e3d" default))
|
||||||
|
)
|
||||||
|
|
Reference in a new issue