From c9218804220c496d0c841eecaa0c8b6a92146880 Mon Sep 17 00:00:00 2001 From: jao Date: Mon, 11 Jan 2021 01:14:36 +0000 Subject: more consult functions, new jao-embark, eos --- eos/sys/jao-ednc.el | 141 ++++++++++++++++++++++++++++++++++++++++++++++ eos/sys/jao-embark.el | 62 ++++++++++++++++++++ eos/sys/jao-minibuffer.el | 133 +++++++++++++++++++++++++++++++++++++++++++ eos/sys/jao-notify.el | 33 +++++++++++ eos/sys/jao-osd.el | 55 ++++++++++++++++++ eos/sys/jao-sleep.el | 58 +++++++++++++++++++ media/espotify.org | 58 ++++++++++++------- readme.org | 2 +- sys/jao-ednc.el | 141 ---------------------------------------------- sys/jao-minibuffer.el | 133 ------------------------------------------- sys/jao-notify.el | 33 ----------- sys/jao-osd.el | 55 ------------------ sys/jao-sleep.el | 58 ------------------- 13 files changed, 520 insertions(+), 442 deletions(-) create mode 100644 eos/sys/jao-ednc.el create mode 100644 eos/sys/jao-embark.el create mode 100644 eos/sys/jao-minibuffer.el create mode 100644 eos/sys/jao-notify.el create mode 100644 eos/sys/jao-osd.el create mode 100644 eos/sys/jao-sleep.el delete mode 100644 sys/jao-ednc.el delete mode 100644 sys/jao-minibuffer.el delete mode 100644 sys/jao-notify.el delete mode 100644 sys/jao-osd.el delete mode 100644 sys/jao-sleep.el diff --git a/eos/sys/jao-ednc.el b/eos/sys/jao-ednc.el new file mode 100644 index 0000000..03d4049 --- /dev/null +++ b/eos/sys/jao-ednc.el @@ -0,0 +1,141 @@ +;;; jao-ednc.el --- Minibuffer notifications using EDNC -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 jao + +;; Author: jao +;; Keywords: tools, abbrev + +;; 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 . + +;;; Commentary: + +;; Use the ednc package to provide a notification daemon that uses +;; the minibuffer to display them. + +;;; Code: + +(require 'ednc) +(require 'jao-minibuffer) + +(declare-function tracking-add-buffer "tracking") +(declare-function tracking-remove-buffer "tracking") + +(defvar jao-ednc--count-format " {%d} ") +(defvar jao-ednc--notifications ()) +(defvar jao-ednc--handlers ()) + +(defvar jao-ednc-use-minibuffer-notifications nil) +(defvar jao-ednc-use-tracking t) + +(defface jao-ednc-tracking '((t :inherit warning)) + "Tracking notifications face" + :group 'jao-ednc) + +(defun jao-ednc--last-notification () (car jao-ednc--notifications)) + +(defun jao-ednc--format-last () + (when (jao-ednc--last-notification) + (let ((s (ednc-format-notification (jao-ednc--last-notification) t))) + (replace-regexp-in-string "\n" " " (substring-no-properties s))))) + +(defun jao-ednc--count () + (let ((no (length jao-ednc--notifications))) + (if (> no 0) + (propertize (format jao-ednc--count-format no) 'face 'warning) + ""))) + +(defun jao-ednc-add-handler (app handler) + (add-to-list 'jao-ednc--handlers (cons app handler))) + +(defun jao-ednc-ignore-app (app) + (jao-ednc-add-handler app (lambda (not _) (ednc-dismiss-notification not)))) + +(defun jao-ednc--pop-minibuffer () + (if jao-ednc-use-minibuffer-notifications + (jao-minibuffer-pop-notification) + (jao-minibuffer-refresh))) + +(defun jao-ednc--clean (&optional notification) + (tracking-remove-buffer (get-buffer ednc-log-name)) + (if notification + (remove notification jao-ednc--notifications) + (pop jao-ednc--notifications)) + (jao-ednc--pop-minibuffer)) + +(defun jao-ednc--show-last () + (if jao-ednc-use-minibuffer-notifications + (jao-minibuffer-push-notification '(:eval (jao-ednc--format-last))) + (message "%s" (jao-ednc--format-last)))) + +(defun jao-ednc--default-handler (notification newp) + (if (not newp) + (jao-ednc--clean notification) + (tracking-add-buffer (get-buffer ednc-log-name) '(jao-ednc-tracking)) + (push notification jao-ednc--notifications) + (jao-ednc--show-last))) + +(defun jao-ednc--handler (notification) + (alist-get (ednc-notification-app-name notification) + jao-ednc--handlers + #'jao-ednc--default-handler + nil + 'string=)) + +(defun jao-ednc--on-notify (old new) + (when old (funcall (jao-ednc--handler old) old nil)) + (when new (funcall (jao-ednc--handler new) new t))) + +;;;###autoload +(defun jao-ednc-setup (minibuffer-order) + (setq jao-notify-use-messages-p t) + (with-eval-after-load "tracking" + (when jao-ednc-use-tracking + (add-to-list 'tracking-faces-priorities 'jao-ednc-tracking) + (when (listp tracking-shorten-modes) + (add-to-list 'tracking-shorten-modes 'ednc-view-mode)))) + (jao-minibuffer-add-variable '(jao-ednc--count) minibuffer-order) + (add-hook 'ednc-notification-presentation-functions #'jao-ednc--on-notify) + (ednc-mode)) + +;;;###autoload +(defun jao-ednc-pop () + (interactive) + (pop-to-buffer-same-window ednc-log-name)) + +;;;###autoload +(defun jao-ednc-show () + (interactive) + (if (not (jao-ednc--last-notification)) + (jao-ednc-pop) + (jao-ednc--show-last))) + +;;;###autoload +(defun jao-ednc-invoke-last-action () + (interactive) + (if (jao-ednc--last-notification) + (ednc-invoke-action (jao-ednc--last-notification)) + (message "No active notifications")) + (jao-ednc--clean)) + +;;;###autoload +(defun jao-ednc-dismiss () + (interactive) + (when (jao-ednc--last-notification) + (ignore-errors + (with-current-buffer ednc-log-name + (ednc-dismiss-notification (jao-ednc--last-notification))))) + (jao-ednc--clean)) + +(provide 'jao-ednc) +;;; jao-ednc.el ends here diff --git a/eos/sys/jao-embark.el b/eos/sys/jao-embark.el new file mode 100644 index 0000000..9572489 --- /dev/null +++ b/eos/sys/jao-embark.el @@ -0,0 +1,62 @@ +;;; jao-embark.el --- embark actions -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 jao + +;; Author: jao +;; Keywords: convenience + +;; 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 . + +;;; Commentary: + +;; Actions and utilities for embark + +;;; Code: + +(require 'embark) + +(defvar jao-embark-video-url-rx + (format "^https?://\\(?:www\\.\\)?%s/.+" + (regexp-opt '("youtu.be" + "youtube.com" + "blip.tv" + "vimeo.com" + "infoq.com") + t)) + "A regular expression matching URLs that point to video streams") + +(defun jao-embark-video-finder () + "Check whether we're looking at a video URL. +Return (video-url . ) if so." + (when-let ((url (thing-at-point-url-at-point))) + (when (string-match-p jao-embark-video-url-rx url) + (cons 'video-url url)))) + +(defun jao-embark-play-video-url (&optional url) + (interactive "sURL: ") + (let ((cmd (format "mpv %s" (shell-quote-argument url)))) + (start-process-shell-command "mpv" nil cmd))) + +(add-to-list 'embark-target-finders #'jao-embark-video-finder) + +(embark-define-keymap jao-embark-video-url-map + "Actions on URLs pointing to remote video streams." + ("p" jao-embark-play-video-url) + ("b" browse-url) + ("f" browse-url-firefox)) + +(add-to-list 'embark-keymap-alist '(video-url . jao-embark-video-url-map)) + +(provide 'jao-embark) +;;; jao-embark.el ends here diff --git a/eos/sys/jao-minibuffer.el b/eos/sys/jao-minibuffer.el new file mode 100644 index 0000000..b626151 --- /dev/null +++ b/eos/sys/jao-minibuffer.el @@ -0,0 +1,133 @@ +;;; jao-minibuffer.el --- using the minibuffer to report status -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 jao + +;; Author: jao +;; Keywords: extensions + +;; 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 . + +;;; Commentary: + +;; Simple asynchronous display of information in the minibuffer. + +;;; Code: + +(defvar jao-minibuffer-info ()) +(defvar jao-minibuffer-notification nil) +(defvar jao-minibuffer-align-right-p t) +(defvar jao-minibuffer-right-margin (if window-system 0 1)) +(defvar jao-minibuffer-maximized-frames-p nil) +(defvar jao-minibuffer-frame-width nil) +(defvar jao-minibuffer-notification-timeout 5) +(defvar jao-minibuffer-enabled-p t) + +(defconst jao-minibuffer--name " *Minibuf-0*") + +(defun jao-minibuffer--trim (s w) + (if (<= (length s) w) + (format (format "%%%ds" (if jao-minibuffer-align-right-p w (- w))) s) + (substring s 0 w))) + +(defun jao-minibuffer--current () + (with-current-buffer jao-minibuffer--name + (buffer-substring (point-min) (point-max)))) + +(defun jao-minibuffer--width () + (cond ((numberp jao-minibuffer-frame-width) jao-minibuffer-frame-width) + (jao-minibuffer-maximized-frames-p (frame-width)) + (t (min (frame-width) (window-width (minibuffer-window)))))) + +(defun jao-minibuffer--format-info () + (mapconcat 'string-trim + (seq-filter (lambda (s) (not (string-blank-p s))) + (mapcar 'format-mode-line + (if jao-minibuffer-align-right-p + jao-minibuffer-info + (reverse jao-minibuffer-info)))) + " ")) + +(defun jao-minibuffer--aligned (&optional w currentp) + (let* ((msg (cond (currentp (jao-minibuffer--current)) + (jao-minibuffer-notification + (format-mode-line jao-minibuffer-notification)) + (t (jao-minibuffer--format-info)))) + (msg (if jao-minibuffer-align-right-p + (string-trim msg) + (string-trim-left msg))) + (msg (propertize msg :minibuffer-message t))) + (when (not (string-empty-p msg)) + (let* ((mw (jao-minibuffer--width)) + (w (mod (or w (length (current-message))) mw)) + (w (- mw w jao-minibuffer-right-margin))) + (if (> w 0) (jao-minibuffer--trim msg w) ""))))) + +(defun jao-minibuffer--set-message (msg) + (let ((msg (string-trim (replace-regexp-in-string "\n" " " msg)))) + (if jao-minibuffer-align-right-p + (concat msg (jao-minibuffer--aligned (length msg) t)) + (concat (jao-minibuffer--aligned (+ 3 (length msg)) t) " " msg)))) + +(defun jao-minibuffer--insert (msg) + (with-current-buffer jao-minibuffer--name + (erase-buffer) + (insert msg))) + +;;;###autoload +(defun jao-minibuffer-refresh () + (interactive) + (when jao-minibuffer-enabled-p + (jao-minibuffer--insert (or (jao-minibuffer--aligned) "")))) + +;;;###autoload +(defun jao-minibuffer-add-variable (variable-name &optional order) + (add-to-ordered-list 'jao-minibuffer-info `(:eval ,variable-name) order)) + +(defvar jao-minibuffer--notification-timer nil) + +(defun jao-minibuffer--start-notification-timer (timeout) + (interactive) + (when jao-minibuffer--notification-timer + (cancel-timer jao-minibuffer--notification-timer)) + (setq jao-minibuffer--notification-timer + (run-with-idle-timer (or timeout jao-minibuffer-notification-timeout) + nil + 'jao-minibuffer-pop-notification))) + +;;;###autoload +(defun jao-minibuffer-push-notification (msg &optional timeout) + (setq jao-minibuffer-notification msg) + (jao-minibuffer--start-notification-timer timeout) + (jao-minibuffer-refresh)) + +;;;###autoload +(defun jao-minibuffer-pop-notification () + (interactive) + (setq jao-minibuffer-notification nil) + (jao-minibuffer-refresh)) + +;;;###autoload +(defun jao-minibuffer-toggle () + (interactive) + (setq jao-minibuffer-enabled-p (not jao-minibuffer-enabled-p)) + (if jao-minibuffer-enabled-p + (jao-minibuffer-refresh) + (jao-minibuffer--insert ""))) + +(setq set-message-function #'jao-minibuffer--set-message) +(setq clear-message-function #'jao-minibuffer-refresh) +(setq resize-mini-windows nil) + +(provide 'jao-minibuffer) +;;; jao-minibuffer.el ends here diff --git a/eos/sys/jao-notify.el b/eos/sys/jao-notify.el new file mode 100644 index 0000000..dc48ca4 --- /dev/null +++ b/eos/sys/jao-notify.el @@ -0,0 +1,33 @@ +;; jao-notify.el -- Interacting with notification daemon + +;; Copyright (c) 2017, 2019, 2020 Jose Antonio Ortega Ruiz + +;; Author: Jose Antonio Ortega Ruiz +;; Start date: Sun Jan 08, 2017 20:24 + + +;;; Comentary: + +;; Simple notifications using echo or dbus notifications + +;;; Code: + +(defvar jao-notify-use-messages-p nil) +(defvar jao-notify-timeout 5000) + +(declare-function notifications-notify "notifications") + +(defun jao-notify (msg &optional title icon) + (if jao-notify-use-messages-p + (message "%s%s%s" (or title "") (if title ": " "") (or msg "")) + (let* ((args `(:timeout ,jao-notify-timeout)) + (args (append args + (if title `(:title ,title :body ,msg) `(:title ,msg)))) + (args (if (and (stringp icon) (file-exists-p icon)) + (append args `(:app-icon ,(format "%s" icon))) + args))) + (apply 'notifications-notify args)))) + + +(provide 'jao-notify) +;;; jao-notify.el ends here diff --git a/eos/sys/jao-osd.el b/eos/sys/jao-osd.el new file mode 100644 index 0000000..acdc629 --- /dev/null +++ b/eos/sys/jao-osd.el @@ -0,0 +1,55 @@ +;; candy +(defvar jao-osd-cat-color-fg "black") +(defvar jao-osd-cat-color-bg "white") +(defvar jao-osd-cat-font "Andika Basic 16") +;; (setq jao-osd-cat-font "Inconsolata 20") +(defun jao-osd-cat-font (&optional font) + (or font jao-osd-cat-font)) + +(defun jao-osd-process-args (&optional font fg bg) + `("-n" ,(jao-osd-cat-font font) + "-R" ,(or bg jao-osd-cat-color-fg) "-B" ,(or fg jao-osd-cat-color-bg) + "-b" "200" "-r" "255" + "-e" "0" "-t" "2" "-d" "10" "-p" "0" "-x" "10" "-y" "10" "-u" "5000")) + +(setq jao-osd-processes (make-hash-table)) + +(defsubst jao-osd--delete-process (name) + (remhash name jao-osd-processes)) + +(defun jao-osd-process (name &optional font color) + (let ((proc (gethash name jao-osd-processes))) + (or (and proc (eq (process-status proc) 'run) proc) + (puthash name + (apply 'start-process + `("notifications" + ,(format "*notifications/%s*" name) + "aosd_cat" + ,@(jao-osd-process-args))) + jao-osd-processes)))) + +(defun jao-osd-cat (name lines) + (let* ((proc (jao-osd-process name)) + (lines (if (listp lines) lines (list lines))) + (trail (- 5 (length lines)))) + (when proc + (dolist (line lines) + (send-string proc (format "%s\n" line)))))) + ; (when (> trail 0) (send-string proc (make-string trail ?\n)))))) + +(defun jao-osd--names () + (let (names) + (maphash (lambda (n k) (push n names)) jao-osd-processes) + (reverse names))) + +(defun jao-osd-kill (name) + (let ((proc (gethash name jao-osd-processes))) + (when (processp proc) + (kill-process proc)))) + +(defun jao-osd-kill-notifiers () + (interactive) + (maphash (lambda (n p) (ignore-errors (kill-process p))) jao-osd-processes) + (clrhash jao-osd-processes)) + +(provide 'jao-osd) diff --git a/eos/sys/jao-sleep.el b/eos/sys/jao-sleep.el new file mode 100644 index 0000000..93da0e7 --- /dev/null +++ b/eos/sys/jao-sleep.el @@ -0,0 +1,58 @@ +;;; jao-sleep.el --- Actions upon sleep/awake -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 jao + +;; Author: jao +;; Keywords: hardware + +;; 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 . + +;;; Code: + +(require 'dbus) + +(defvar jao-sleep-sleep-functions nil) +(defvar jao-sleep-awake-functions nil) + +(defvar jao-sleep--dbus-registration-object nil) + +(defun jao-sleep--dbus-sleep-handler (sleep-start) + (condition-case nil + (if sleep-start + (progn (message "Running on sleep functions") + (run-hooks 'jao-sleep-sleep-functions)) + (message "Running on awake functions") + (run-hooks 'jao-sleep-awake-functions)) + (error (message "There was an error running %s" sleep-start)))) + +;;;###autoload +(defun jao-sleep-dbus-register (&optional session-dbus) + "Register actions to take on sleep and on awake, using the system D-BUS." + (when (featurep 'dbusbind) + (setq jao-sleep--dbus-sleep-registration-object + (dbus-register-signal (if session-dbus :session :system) + "org.freedesktop.login1" + "/org/freedesktop/login1" + "org.freedesktop.login1.Manager" + "PrepareForSleep" + #'jao-sleep--dbus-sleep-handler)))) + +;;;###autoload +(defun jao-sleep-dbus-unregister () + (condition-case nil + (dbus-unregister-object jao-sleep--dbus-sleep-registration-object) + (wrong-type-argument nil))) + +(provide 'jao-sleep) +;;; jao-sleep.el ends here diff --git a/media/espotify.org b/media/espotify.org index 6c07259..5cc0fee 100644 --- a/media/espotify.org +++ b/media/espotify.org @@ -11,10 +11,6 @@ track or album identifier that we can send then to the latter to play, with emacs completion mechanisms (consult and friends in this case) providing the glue between both worlds. -Note: you can access this post as an ~org~ file in my [[https://codeberg.org/jao/elibs/src/branch/main/media/espotify.org][jao/elibs -repository]], and transform it to an emacs-lisp file with ~M-x -org-babel-tangle~. - Let's start with an umbrella customization group: #+begin_src emacs-lisp ;;; espotify.el - spotify search and play - -*- lexical-binding: t; -*- @@ -197,6 +193,19 @@ Let's start with an umbrella customization group: | album_type | artists | available_markets | external_urls | href | id | images | name | release_date | release_date_precision | total_tracks | type | uri | | external_urls | followers | genres | href | id | images | name | popularity | type | uri | | | | + Another strategy would be to search for several types and pass to + our callback the concatenation of all items: + + #+begin_src emacs-lisp + (defun espotify-search-all (callback term &optional types filter) + (let ((types (or types '(album track artist playlist)))) + (espotify-search* (lambda (&rest items) + (funcall callback (apply append items))) + term + types + filter))) + #+end_src + * Sending commands to local players Once we now the URI we want to play (that ~uri~ entry in our items), @@ -283,7 +292,7 @@ Let's start with an umbrella customization group: ((or 'setup 'refresh) (funcall next action)) ('destroy (setq candidates nil) (funcall next 'destroy)) ((pred stringp) - (espotify-search* + (espotify-search-all (lambda (x) (setq candidates (mapcar 'espotify--format-item x)) (funcall next candidates)) @@ -339,6 +348,26 @@ Let's start with an umbrella customization group: (espotify--maybe-play (consult-spotify-by 'album filter))) #+end_src + And likewise for playlists, artists and combinations thereof: + + #+begin_src emacs-lisp + (defun consult-spotify-artist (&optional filter) + (interactive) + (espotify--maybe-play (consult-spotify-by 'artist filter))) + #+end_src + + #+begin_src emacs-lisp + (defun consult-spotify-track (&optional filter) + (interactive) + (espotify--maybe-play (consult-spotify-by 'track filter))) + #+end_src + + #+begin_src emacs-lisp + (defun consult-spotify-playlist (&optional filter) + (interactive) + (espotify--maybe-play (consult-spotify-by 'playlist filter))) + #+end_src + * Adding metadata to candidates using Marginalia Let's add metadata fields to our candidates, so that packages like @@ -358,28 +387,15 @@ Let's start with an umbrella customization group: (add-to-list 'marginalia-annotators-heavy (cons 'spotify-query-result 'espotify-marginalia-annotate)) - #+end_src - -* Exercises for the reader - - Defining new interactive commands for other types and queries, - as well as standard filters shouldn't be too complicated now that we - have the above tools at our disposal. - - For instance: - #+begin_src emacs-lisp - (defun consult-spotify-playlist (&optional filter) - (interactive) - (espotify--maybe-play (consult-spotify-by 'playlist filter))) - #+end_src - +#+end_src -* Post-amble :notes: +* Post-amble :noexport: #+begin_src emacs-lisp (provide 'espotify) #+end_src + * Footnotes [fn:1] This is an elegant strategy i first learnt about in SICP, many, diff --git a/readme.org b/readme.org index c40ea97..ac4fd03 100644 --- a/readme.org +++ b/readme.org @@ -2,13 +2,13 @@ *** Sections + - [[./eos][eos]] generic utilities for the emacs operating system - [[./themes][themes]] color themes based on Emacs builtin custom themes - [[org][org]] utilities for org-mode - [[./doc][doc]] opening documents (pdfs, mostly) - [[./media][media]] utilities for music players and the like - [[./prog][prog]] utilities for compilation and programming modes - [[./net][net]] utilities for networking (w3m, weather &c.) - - [[./sys][sys]] generic utilities for external programs - [[./bmk][bmk]] a web bookmark manager See also my [[https://jao.io/cgit/emacs][emacs custom files]]. diff --git a/sys/jao-ednc.el b/sys/jao-ednc.el deleted file mode 100644 index 03d4049..0000000 --- a/sys/jao-ednc.el +++ /dev/null @@ -1,141 +0,0 @@ -;;; jao-ednc.el --- Minibuffer notifications using EDNC -*- lexical-binding: t; -*- - -;; Copyright (C) 2020 jao - -;; Author: jao -;; Keywords: tools, abbrev - -;; 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 . - -;;; Commentary: - -;; Use the ednc package to provide a notification daemon that uses -;; the minibuffer to display them. - -;;; Code: - -(require 'ednc) -(require 'jao-minibuffer) - -(declare-function tracking-add-buffer "tracking") -(declare-function tracking-remove-buffer "tracking") - -(defvar jao-ednc--count-format " {%d} ") -(defvar jao-ednc--notifications ()) -(defvar jao-ednc--handlers ()) - -(defvar jao-ednc-use-minibuffer-notifications nil) -(defvar jao-ednc-use-tracking t) - -(defface jao-ednc-tracking '((t :inherit warning)) - "Tracking notifications face" - :group 'jao-ednc) - -(defun jao-ednc--last-notification () (car jao-ednc--notifications)) - -(defun jao-ednc--format-last () - (when (jao-ednc--last-notification) - (let ((s (ednc-format-notification (jao-ednc--last-notification) t))) - (replace-regexp-in-string "\n" " " (substring-no-properties s))))) - -(defun jao-ednc--count () - (let ((no (length jao-ednc--notifications))) - (if (> no 0) - (propertize (format jao-ednc--count-format no) 'face 'warning) - ""))) - -(defun jao-ednc-add-handler (app handler) - (add-to-list 'jao-ednc--handlers (cons app handler))) - -(defun jao-ednc-ignore-app (app) - (jao-ednc-add-handler app (lambda (not _) (ednc-dismiss-notification not)))) - -(defun jao-ednc--pop-minibuffer () - (if jao-ednc-use-minibuffer-notifications - (jao-minibuffer-pop-notification) - (jao-minibuffer-refresh))) - -(defun jao-ednc--clean (&optional notification) - (tracking-remove-buffer (get-buffer ednc-log-name)) - (if notification - (remove notification jao-ednc--notifications) - (pop jao-ednc--notifications)) - (jao-ednc--pop-minibuffer)) - -(defun jao-ednc--show-last () - (if jao-ednc-use-minibuffer-notifications - (jao-minibuffer-push-notification '(:eval (jao-ednc--format-last))) - (message "%s" (jao-ednc--format-last)))) - -(defun jao-ednc--default-handler (notification newp) - (if (not newp) - (jao-ednc--clean notification) - (tracking-add-buffer (get-buffer ednc-log-name) '(jao-ednc-tracking)) - (push notification jao-ednc--notifications) - (jao-ednc--show-last))) - -(defun jao-ednc--handler (notification) - (alist-get (ednc-notification-app-name notification) - jao-ednc--handlers - #'jao-ednc--default-handler - nil - 'string=)) - -(defun jao-ednc--on-notify (old new) - (when old (funcall (jao-ednc--handler old) old nil)) - (when new (funcall (jao-ednc--handler new) new t))) - -;;;###autoload -(defun jao-ednc-setup (minibuffer-order) - (setq jao-notify-use-messages-p t) - (with-eval-after-load "tracking" - (when jao-ednc-use-tracking - (add-to-list 'tracking-faces-priorities 'jao-ednc-tracking) - (when (listp tracking-shorten-modes) - (add-to-list 'tracking-shorten-modes 'ednc-view-mode)))) - (jao-minibuffer-add-variable '(jao-ednc--count) minibuffer-order) - (add-hook 'ednc-notification-presentation-functions #'jao-ednc--on-notify) - (ednc-mode)) - -;;;###autoload -(defun jao-ednc-pop () - (interactive) - (pop-to-buffer-same-window ednc-log-name)) - -;;;###autoload -(defun jao-ednc-show () - (interactive) - (if (not (jao-ednc--last-notification)) - (jao-ednc-pop) - (jao-ednc--show-last))) - -;;;###autoload -(defun jao-ednc-invoke-last-action () - (interactive) - (if (jao-ednc--last-notification) - (ednc-invoke-action (jao-ednc--last-notification)) - (message "No active notifications")) - (jao-ednc--clean)) - -;;;###autoload -(defun jao-ednc-dismiss () - (interactive) - (when (jao-ednc--last-notification) - (ignore-errors - (with-current-buffer ednc-log-name - (ednc-dismiss-notification (jao-ednc--last-notification))))) - (jao-ednc--clean)) - -(provide 'jao-ednc) -;;; jao-ednc.el ends here diff --git a/sys/jao-minibuffer.el b/sys/jao-minibuffer.el deleted file mode 100644 index b626151..0000000 --- a/sys/jao-minibuffer.el +++ /dev/null @@ -1,133 +0,0 @@ -;;; jao-minibuffer.el --- using the minibuffer to report status -*- lexical-binding: t; -*- - -;; Copyright (C) 2020 jao - -;; Author: jao -;; Keywords: extensions - -;; 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 . - -;;; Commentary: - -;; Simple asynchronous display of information in the minibuffer. - -;;; Code: - -(defvar jao-minibuffer-info ()) -(defvar jao-minibuffer-notification nil) -(defvar jao-minibuffer-align-right-p t) -(defvar jao-minibuffer-right-margin (if window-system 0 1)) -(defvar jao-minibuffer-maximized-frames-p nil) -(defvar jao-minibuffer-frame-width nil) -(defvar jao-minibuffer-notification-timeout 5) -(defvar jao-minibuffer-enabled-p t) - -(defconst jao-minibuffer--name " *Minibuf-0*") - -(defun jao-minibuffer--trim (s w) - (if (<= (length s) w) - (format (format "%%%ds" (if jao-minibuffer-align-right-p w (- w))) s) - (substring s 0 w))) - -(defun jao-minibuffer--current () - (with-current-buffer jao-minibuffer--name - (buffer-substring (point-min) (point-max)))) - -(defun jao-minibuffer--width () - (cond ((numberp jao-minibuffer-frame-width) jao-minibuffer-frame-width) - (jao-minibuffer-maximized-frames-p (frame-width)) - (t (min (frame-width) (window-width (minibuffer-window)))))) - -(defun jao-minibuffer--format-info () - (mapconcat 'string-trim - (seq-filter (lambda (s) (not (string-blank-p s))) - (mapcar 'format-mode-line - (if jao-minibuffer-align-right-p - jao-minibuffer-info - (reverse jao-minibuffer-info)))) - " ")) - -(defun jao-minibuffer--aligned (&optional w currentp) - (let* ((msg (cond (currentp (jao-minibuffer--current)) - (jao-minibuffer-notification - (format-mode-line jao-minibuffer-notification)) - (t (jao-minibuffer--format-info)))) - (msg (if jao-minibuffer-align-right-p - (string-trim msg) - (string-trim-left msg))) - (msg (propertize msg :minibuffer-message t))) - (when (not (string-empty-p msg)) - (let* ((mw (jao-minibuffer--width)) - (w (mod (or w (length (current-message))) mw)) - (w (- mw w jao-minibuffer-right-margin))) - (if (> w 0) (jao-minibuffer--trim msg w) ""))))) - -(defun jao-minibuffer--set-message (msg) - (let ((msg (string-trim (replace-regexp-in-string "\n" " " msg)))) - (if jao-minibuffer-align-right-p - (concat msg (jao-minibuffer--aligned (length msg) t)) - (concat (jao-minibuffer--aligned (+ 3 (length msg)) t) " " msg)))) - -(defun jao-minibuffer--insert (msg) - (with-current-buffer jao-minibuffer--name - (erase-buffer) - (insert msg))) - -;;;###autoload -(defun jao-minibuffer-refresh () - (interactive) - (when jao-minibuffer-enabled-p - (jao-minibuffer--insert (or (jao-minibuffer--aligned) "")))) - -;;;###autoload -(defun jao-minibuffer-add-variable (variable-name &optional order) - (add-to-ordered-list 'jao-minibuffer-info `(:eval ,variable-name) order)) - -(defvar jao-minibuffer--notification-timer nil) - -(defun jao-minibuffer--start-notification-timer (timeout) - (interactive) - (when jao-minibuffer--notification-timer - (cancel-timer jao-minibuffer--notification-timer)) - (setq jao-minibuffer--notification-timer - (run-with-idle-timer (or timeout jao-minibuffer-notification-timeout) - nil - 'jao-minibuffer-pop-notification))) - -;;;###autoload -(defun jao-minibuffer-push-notification (msg &optional timeout) - (setq jao-minibuffer-notification msg) - (jao-minibuffer--start-notification-timer timeout) - (jao-minibuffer-refresh)) - -;;;###autoload -(defun jao-minibuffer-pop-notification () - (interactive) - (setq jao-minibuffer-notification nil) - (jao-minibuffer-refresh)) - -;;;###autoload -(defun jao-minibuffer-toggle () - (interactive) - (setq jao-minibuffer-enabled-p (not jao-minibuffer-enabled-p)) - (if jao-minibuffer-enabled-p - (jao-minibuffer-refresh) - (jao-minibuffer--insert ""))) - -(setq set-message-function #'jao-minibuffer--set-message) -(setq clear-message-function #'jao-minibuffer-refresh) -(setq resize-mini-windows nil) - -(provide 'jao-minibuffer) -;;; jao-minibuffer.el ends here diff --git a/sys/jao-notify.el b/sys/jao-notify.el deleted file mode 100644 index dc48ca4..0000000 --- a/sys/jao-notify.el +++ /dev/null @@ -1,33 +0,0 @@ -;; jao-notify.el -- Interacting with notification daemon - -;; Copyright (c) 2017, 2019, 2020 Jose Antonio Ortega Ruiz - -;; Author: Jose Antonio Ortega Ruiz -;; Start date: Sun Jan 08, 2017 20:24 - - -;;; Comentary: - -;; Simple notifications using echo or dbus notifications - -;;; Code: - -(defvar jao-notify-use-messages-p nil) -(defvar jao-notify-timeout 5000) - -(declare-function notifications-notify "notifications") - -(defun jao-notify (msg &optional title icon) - (if jao-notify-use-messages-p - (message "%s%s%s" (or title "") (if title ": " "") (or msg "")) - (let* ((args `(:timeout ,jao-notify-timeout)) - (args (append args - (if title `(:title ,title :body ,msg) `(:title ,msg)))) - (args (if (and (stringp icon) (file-exists-p icon)) - (append args `(:app-icon ,(format "%s" icon))) - args))) - (apply 'notifications-notify args)))) - - -(provide 'jao-notify) -;;; jao-notify.el ends here diff --git a/sys/jao-osd.el b/sys/jao-osd.el deleted file mode 100644 index acdc629..0000000 --- a/sys/jao-osd.el +++ /dev/null @@ -1,55 +0,0 @@ -;; candy -(defvar jao-osd-cat-color-fg "black") -(defvar jao-osd-cat-color-bg "white") -(defvar jao-osd-cat-font "Andika Basic 16") -;; (setq jao-osd-cat-font "Inconsolata 20") -(defun jao-osd-cat-font (&optional font) - (or font jao-osd-cat-font)) - -(defun jao-osd-process-args (&optional font fg bg) - `("-n" ,(jao-osd-cat-font font) - "-R" ,(or bg jao-osd-cat-color-fg) "-B" ,(or fg jao-osd-cat-color-bg) - "-b" "200" "-r" "255" - "-e" "0" "-t" "2" "-d" "10" "-p" "0" "-x" "10" "-y" "10" "-u" "5000")) - -(setq jao-osd-processes (make-hash-table)) - -(defsubst jao-osd--delete-process (name) - (remhash name jao-osd-processes)) - -(defun jao-osd-process (name &optional font color) - (let ((proc (gethash name jao-osd-processes))) - (or (and proc (eq (process-status proc) 'run) proc) - (puthash name - (apply 'start-process - `("notifications" - ,(format "*notifications/%s*" name) - "aosd_cat" - ,@(jao-osd-process-args))) - jao-osd-processes)))) - -(defun jao-osd-cat (name lines) - (let* ((proc (jao-osd-process name)) - (lines (if (listp lines) lines (list lines))) - (trail (- 5 (length lines)))) - (when proc - (dolist (line lines) - (send-string proc (format "%s\n" line)))))) - ; (when (> trail 0) (send-string proc (make-string trail ?\n)))))) - -(defun jao-osd--names () - (let (names) - (maphash (lambda (n k) (push n names)) jao-osd-processes) - (reverse names))) - -(defun jao-osd-kill (name) - (let ((proc (gethash name jao-osd-processes))) - (when (processp proc) - (kill-process proc)))) - -(defun jao-osd-kill-notifiers () - (interactive) - (maphash (lambda (n p) (ignore-errors (kill-process p))) jao-osd-processes) - (clrhash jao-osd-processes)) - -(provide 'jao-osd) diff --git a/sys/jao-sleep.el b/sys/jao-sleep.el deleted file mode 100644 index 93da0e7..0000000 --- a/sys/jao-sleep.el +++ /dev/null @@ -1,58 +0,0 @@ -;;; jao-sleep.el --- Actions upon sleep/awake -*- lexical-binding: t; -*- - -;; Copyright (C) 2020 jao - -;; Author: jao -;; Keywords: hardware - -;; 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 . - -;;; Code: - -(require 'dbus) - -(defvar jao-sleep-sleep-functions nil) -(defvar jao-sleep-awake-functions nil) - -(defvar jao-sleep--dbus-registration-object nil) - -(defun jao-sleep--dbus-sleep-handler (sleep-start) - (condition-case nil - (if sleep-start - (progn (message "Running on sleep functions") - (run-hooks 'jao-sleep-sleep-functions)) - (message "Running on awake functions") - (run-hooks 'jao-sleep-awake-functions)) - (error (message "There was an error running %s" sleep-start)))) - -;;;###autoload -(defun jao-sleep-dbus-register (&optional session-dbus) - "Register actions to take on sleep and on awake, using the system D-BUS." - (when (featurep 'dbusbind) - (setq jao-sleep--dbus-sleep-registration-object - (dbus-register-signal (if session-dbus :session :system) - "org.freedesktop.login1" - "/org/freedesktop/login1" - "org.freedesktop.login1.Manager" - "PrepareForSleep" - #'jao-sleep--dbus-sleep-handler)))) - -;;;###autoload -(defun jao-sleep-dbus-unregister () - (condition-case nil - (dbus-unregister-object jao-sleep--dbus-sleep-registration-object) - (wrong-type-argument nil))) - -(provide 'jao-sleep) -;;; jao-sleep.el ends here -- cgit v1.2.3