;;; ement-macros.el --- Ement macros -*- lexical-binding: t; -*- ;; Copyright (C) 2020 Adam Porter ;; Author: Adam Porter ;; Keywords: ;; 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: ;; ;;; Code: ;;;; Requirements (require 'map) ;;;; Debugging (eval-and-compile (setq-local warning-minimum-log-level nil) (setq-local warning-minimum-log-level :debug)) (cl-defmacro ement-debug (&rest args) "Display a debug warning showing the runtime value of ARGS. The warning automatically includes the name of the containing function, and it is only displayed if `warning-minimum-log-level' is `:debug' at expansion time (otherwise the macro expands to nil and is eliminated by the byte-compiler). When debugging, the form also returns nil so, e.g. it may be used in a conditional in place of nil. Each of ARGS may be a string, which is displayed as-is, or a symbol, the value of which is displayed prefixed by its name, or a Lisp form, which is displayed prefixed by its first symbol. Before the actual ARGS arguments, you can write keyword arguments, i.e. alternating keywords and values. The following keywords are supported: :buffer BUFFER Name of buffer to pass to `display-warning'. :level LEVEL Level passed to `display-warning', which see. Default is :debug." (pcase-let* ((fn-name (with-current-buffer (or byte-compile-current-buffer (current-buffer)) ;; This is a hack, but a nifty one. (save-excursion (beginning-of-defun) (cl-second (read (current-buffer)))))) (plist-args (cl-loop while (keywordp (car args)) collect (pop args) collect (pop args))) ((map (:buffer buffer) (:level level)) plist-args) (level (or level :debug)) (string (cl-loop for arg in args concat (pcase arg ((pred stringp) "%S ") ((pred symbolp) (concat (upcase (symbol-name arg)) ":%S ")) ((pred listp) (concat "(" (upcase (symbol-name (car arg))) (pcase (length arg) (1 ")") (_ "...)")) ":%S ")))))) (when (eq :debug warning-minimum-log-level) `(progn (display-warning ',fn-name (format ,string ,@args) ,level ,buffer) nil)))) ;;;; Macros (defmacro ement-alist (&rest pairs) "Expand to an alist of the keys and values in PAIRS." `(list ,@(cl-loop for (key value) on pairs by #'cddr collect `(cons ,key ,value)))) ;;;; Variables ;;;; Customization ;;;; Commands ;;;; Functions ;;;; Footer (provide 'ement-macros) ;;; ement-macros.el ends here