[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/setup b413502 01/17: Initial import
From: |
Stefan Monnier |
Subject: |
[elpa] externals/setup b413502 01/17: Initial import |
Date: |
Sat, 13 Mar 2021 18:15:11 -0500 (EST) |
branch: externals/setup
commit b4135024d4c3d108a81f89cffc18360d4255fa3f
Author: Philip K <philipk@posteo.net>
Commit: Philip K <philipk@posteo.net>
Initial import
---
.dir-locals.el | 5 +
.gitignore | 3 +
LICENSE | 121 +++++++++++++++++++++
README.md | 52 +++++++++
setup.el | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 510 insertions(+)
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..3bcda92
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,5 @@
+;;; Directory Local Variables
+;;; For more information see (info "(emacs) Directory Variables")
+
+((emacs-lisp-mode
+ (indent-tabs-mode . nil)))
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..507dafa
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.elc
+*~
+\#*\#
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0a3e45a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,52 @@
+`setup.el`
+==========
+
+The `setup' macro simplifies repetitive configuration patterns. For
+example, these macros:
+
+ (setup shell
+ (let ((key "C-c s"))
+ (global (key shell))
+ (bind (key bury-buffer))))
+
+
+ (setup (package paredit)
+ (hide-lighter)
+ (hook-into scheme-mode lisp-mode))
+
+will be replaced with the functional equivalent of
+
+ (global-set-key (kbd "C-c s") #'shell)
+ (with-eval-after-load 'shell
+ (define-key shell-mode-map (kbd "C-c s") #'bury-buffer))
+
+
+ (unless (package-install-p 'paredit)
+ (package-install 'paredit ))
+ (delq (assq 'paredit-mode minor-mode-alist)
+ minor-mode-alist)
+ (add-hook 'scheme-mode-hook #'paredit-mode)
+ (add-hook 'lisp-mode-hook #'paredit-mode)
+
+Additional "keywords" can be defined using `setup-define'. Invoke
+the command `setup-help' to get a list of macros.
+
+**Note:** This package is still being developed, and will probably
+change a lot. See [this thread][thread] from emacs-devel for more
+information.
+
+Bugs
+----
+
+Bugs or comments can be submitted to my [public inbox][mail].
+own.
+
+Copying
+-------
+
+`setup.el` is distributed under the [CC0 1.0 Universal (CC0 1.0)
+Public Domain Dedication][cc0] license.
+
+[thread]: https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00188.html
+[mail]: https://lists.sr.ht/~zge/public-inbox
+[cc0]: https://creativecommons.org/publicdomain/zero/1.0/deed
diff --git a/setup.el b/setup.el
new file mode 100644
index 0000000..04323df
--- /dev/null
+++ b/setup.el
@@ -0,0 +1,329 @@
+;;; setup.el --- Helpful Configuration Macro -*- lexical-binding: t -*-
+
+;; Author: Philip K. <philipk@posteo.net>
+;; Maintainer: Philip K. <philipk@posteo.net>
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "26.1") (cl-lib "0.6.1"))
+;; Keywords: lisp, local
+
+;; This file is NOT part of Emacs.
+;;
+;; This file is in the public domain, to the extent possible under law,
+;; published under the CC0 1.0 Universal license.
+;;
+;; For a full copy of the CC0 license see
+;; https://creativecommons.org/publicdomain/zero/1.0/legalcode
+
+;;; Commentary:
+
+;; The `setup' macro simplifies repetitive configuration patterns.
+;; For example, these macros:
+
+;; (setup shell
+;; (let ((key "C-c s"))
+;; (global key shell)
+;; (bind key bury-buffer)))
+;;
+;;
+;; (setup (:package paredit)
+;; (hide-mode)
+;; (hook-into scheme-mode lisp-mode))
+
+;; will be replaced with the functional equivalent of
+
+;; (global-set-key (kbd "C-c s") #'shell)
+;; (with-eval-after-load 'shell
+;; (define-key shell-mode-map (kbd "C-c s") #'bury-buffer))
+;;
+;;
+;; (unless (package-install-p 'paredit)
+;; (package-install 'paredit ))
+;; (delq (assq 'paredit-mode minor-mode-alist)
+;; minor-mode-alist)
+;; (add-hook 'scheme-mode-hook #'paredit-mode)
+;; (add-hook 'lisp-mode-hook #'paredit-mode)
+
+;; Additional "keywords" can be defined using `setup-define'. All
+;; known keywords are documented in the docstring for `setup'.
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+
+
+;;; `setup' macros
+
+(defvar setup-macros nil
+ "Local macro definitions to be bound in `setup' bodies.")
+
+;;;###autoload
+(defun setup-make-docstring ()
+ "Return a docstring for `setup'."
+ (with-temp-buffer
+ (insert (documentation (symbol-function 'setup) 'raw))
+ (dolist (sym (mapcar #'car setup-macros))
+ (let ((sig (if (get sym 'setup-signature)
+ (cons sym (get sym 'setup-signature))
+ (list sym))))
+ (insert "- " (prin1-to-string sig)
+ "\n\n"
+ (or (get sym 'setup-documentation)
+ "No documentation.")
+ "\n\n")))
+ (buffer-string)))
+
+;;;###autoload
+(defmacro setup (name &rest body)
+ "Configure feature or subsystem NAME.
+BODY may contain special forms defined by `setup-define', but
+will otherwise just be evaluated as is.
+
+The following local macros are defined in a `setup' body:\n\n"
+ (declare (debug (name &rest body)))
+ (when (consp name)
+ (let ((shorthand (get (car name) 'setup-shorthand)))
+ (when shorthand
+ (push name body)
+ (setq name (funcall shorthand name)))))
+ (let ((mode (if (string-match-p "-mode\\'" (symbol-name name))
+ name
+ (intern (format "%s-mode" name)))))
+ `(let ((setup-name ',name))
+ (ignore setup-name)
+ (cl-macrolet ,setup-macros
+ (catch 'setup-exit
+ (:with-mode ,mode ,@body))))))
+
+;;;###autoload
+(put 'setup 'function-documentation '(setup-make-docstring))
+
+(defun setup-define (name fn &rest opts)
+ "Define `setup'-local macro NAME using function FN.
+The plist OPTS may contain the key-value pairs:
+
+ :name
+Specify a function to use, for extracting the feature name of a
+NAME entry, if it is the first element in a setup macro.
+
+ :indent
+Change indentation behaviour. See symbol `lisp-indent-function'.
+
+ :after-loaded
+Wrap the macro in a `with-eval-after-load' body.
+
+ :signature
+Give an advertised calling convention.
+
+ :documentation
+A documentation string."
+ (declare (indent 1))
+ (cl-assert (symbolp name))
+ (cl-assert (functionp fn))
+ (cl-assert (listp opts))
+ ;; save metadata
+ (put name 'setup-documentation (plist-get opts :documentation))
+ (put name 'setup-signature (plist-get opts :signature))
+ (put name 'setup-shorthand (plist-get opts :shorthand))
+ (put name 'lisp-indent-function (plist-get opts :indent))
+ (put name 'setup-indent (plist-get opts :indent))
+ ;; forget previous definition
+ (setq setup-macros (delq (assq name setup-macros)
+ setup-macros))
+ ;; define macro for `cl-macrolet'
+ (push (let* ((arity (func-arity fn))
+ (body (if (plist-get opts :repeatable)
+ `(progn
+ (unless (zerop (mod (length args) ,(car arity)))
+ (error "Illegal arguments"))
+ (let (aggr)
+ (while args
+ (let ((rest (nthcdr ,(car arity) args)))
+ (setf (nthcdr ,(car arity) args) nil)
+ (push (apply #',fn args) aggr)
+ (setq args rest)))
+ `(progn ,@(nreverse aggr))))
+ `(apply #',fn args))))
+ (if (plist-get opts :after-loaded)
+ `(,name (&rest args)
+ `(with-eval-after-load setup-name ,,body))
+ `(,name (&rest args) `,,body)))
+ setup-macros)
+ (set-advertised-calling-convention name (plist-get opts :signature) nil))
+
+
+;;; definitions of `setup' keywords
+
+(setup-define 'with-mode
+ (lambda (mode &rest body)
+ `(let ((setup-mode ',mode)
+ (setup-map ',(intern (format "%s-map" mode)))
+ (setup-hook ',(intern (format "%s-hook" mode))))
+ (ignore setup-mode setup-map setup-hook)
+ ,@body))
+ :signature '(MODE &body BODY)
+ :documentation "Change the MODE that BODY is configuring."
+ :indent 1)
+
+(setup-define 'with-map
+ (lambda (map &rest body)
+ `(let ((setup-map ',map))
+ ,@body))
+ :signature '(MAP &body BODY)
+ :documentation "Change the MAP that BODY will bind to"
+ :indent 1)
+
+(setup-define 'with-hook
+ (lambda (hook &rest body)
+ `(let ((setup-hook ',hook))
+ ,@body))
+ :signature '(HOOK &body BODY)
+ :documentation "Change the HOOK that BODY will use."
+ :indent 1)
+
+(setup-define 'package
+ (lambda (package)
+ `(unless (package-installed-p ',package)
+ (package-install ',package)))
+ :signature '(PACKAGE ...)
+ :documentation "Install PACKAGE if it hasn't been installed yet."
+ :shorthand #'cadr
+ :repeatable t)
+
+(setup-define 'require
+ (lambda (feature)
+ `(require ',feature))
+ :signature '(FEATURE ...)
+ :documentation "Eagerly require FEATURE."
+ :shorthand #'cadr
+ :repeatable t)
+
+(setup-define 'global
+ (lambda (key fn)
+ `(global-set-key
+ ,(cond ((stringp key) (kbd key))
+ ((symbolp key) `(kbd ,key))
+ (key))
+ #',fn))
+ :signature '(KEY FUNCTION ...)
+ :documentation "Globally bind KEY to FUNCTION."
+ :repeatable t)
+
+(setup-define 'bind
+ (lambda (key fn)
+ `(define-key (eval setup-map)
+ ,(cond ((stringp key) (kbd key))
+ ((symbolp key) `(kbd ,key))
+ (key))
+ #',fn))
+ :signature '(KEY FUNCTION ...)
+ :documentation "Bind KEY to FUNCTION in current map."
+ :after-loaded t
+ :repeatable t)
+
+(setup-define 'unbind
+ (lambda (key)
+ `(define-key
+ ,(cond ((stringp key) (kbd key))
+ ((symbolp key) `(kbd ,key))
+ (key))
+ nil))
+ :signature '(KEY ...)
+ :documentation "Unbind KEY in current map."
+ :after-loaded t
+ :repeatable t)
+
+(setup-define 'rebind
+ (lambda (key fn)
+ `(progn
+ (dolist (key (where-is-internal ',fn))
+ (define-key (eval setup-map) ,key nil))
+ (define-key
+ ,(cond ((stringp key) (kbd key))
+ ((symbolp key) `(kbd ,key))
+ (key))
+ #',fn)))
+ :signature '(KEY FUNCTION ...)
+ :documentation "Unbind the current key for FUNCTION, and bind it to KEY."
+ :after-loaded t
+ :repeatable t)
+
+(setup-define 'hook
+ (lambda (hook)
+ `(add-hook setup-hook #',hook))
+ :signature '(FUNCTION ...)
+ :documentation "Add FUNCTION to current hook."
+ :repeatable t)
+
+(setup-define 'hook-into
+ (lambda (mode)
+ `(add-hook ',(intern (concat (symbol-name mode) "-hook"))
+ setup-mode))
+ :signature '(HOOK ...)
+ :documentation "Add current mode to HOOK."
+ :repeatable t)
+
+(setup-define 'option
+ (lambda (var val)
+ (cond ((symbolp var)
+ `(customize-set-variable ',var ,val "Modified by `setup'"))
+ ((eq (car-safe var) 'append)
+ `(customize-set-variable
+ ',(cadr var)
+ (append (funcall (or (get ',(cadr var) 'custom-get) 'symbol-value)
+ ',(cadr var))
+ (list ,val))
+ "Modified by `setup'"))
+ ((eq (car-safe var) 'prepend)
+ `(customize-set-variable
+ ',(cadr var)
+ (cons ,val (funcall (or (get ',(cadr var) 'custom-get)
'symbol-value)
+ ',(cadr var)))
+ "Modified by `setup'"))))
+ :signature '(NAME VAL ...)
+ :documentation "Set the option NAME to VAL.
+
+NAME may be a symbol, or a cons-cell. If NAME is a cons-cell, it
+will use the car value to modify the behaviour. If NAME has the
+form (append VAR), "
+ :repeatable t)
+
+(setup-define 'hide-mode
+ (lambda ()
+ `(delq (assq setup-mode minor-mode-alist)
+ minor-mode-alist))
+ :documentation "Hide the mode-line lighter of the current mode."
+ :after-loaded t)
+
+(setup-define 'local-set
+ (lambda (var val)
+ `(add-hook setup-hook (lambda () (setq-local ,var ,val))))
+ :signature '(VAR VAL ...)
+ :documentation "Set the value of VAR to VAL in buffers of the current mode."
+ :repeatable t)
+
+(setup-define 'local-hook
+ (lambda (hook fn)
+ `(add-hook setup-hook
+ (lambda ()
+ (add-hook ',hook #',fn nil t))))
+ :signature '(HOOK FUNCTION ...)
+ :documentation "Add FUNCTION to HOOK only in buffers of the current mode."
+ :repeatable t)
+
+(setup-define 'needs
+ (lambda (binary)
+ `(unless (executable-find ,binary)
+ (throw 'setup-exit nil)))
+ :signature '(PROGRAM ...)
+ :documentation "If PROGRAM is not in the path, stop here."
+ :repeatable t)
+
+(setup-define 'when-loaded
+ (lambda (&rest body) `(progn ,@body))
+ :signature '(&body BODY)
+ :documentation "Evaluate BODY after the current feature has been loaded."
+ :after-loaded t)
+
+(provide 'setup)
+
+;;; setup.el ends here
- [elpa] externals/setup 5b178a4 06/17: Fix issue with :bind, :unbind and :rebind, (continued)
- [elpa] externals/setup 5b178a4 06/17: Fix issue with :bind, :unbind and :rebind, Stefan Monnier, 2021/03/13
- [elpa] externals/setup b000e73 02/17: Use keywords for local macros, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 2624076 07/17: Add general conditional macro :if, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 87fcdf4 12/17: Improve (append ...) and (prepend ...) support, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 3767d24 16/17: Remove explicit dependency on cl-lib, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 912860f 03/17: Update README, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 35b4f18 11/17: Add :also-load macro, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 0bf5c62 09/17: Add :with-feature macro, Stefan Monnier, 2021/03/13
- [elpa] externals/setup d768953 10/17: Sort macros in alphabetical order, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 6ee46ab 14/17: Add support for edebug, Stefan Monnier, 2021/03/13
- [elpa] externals/setup b413502 01/17: Initial import,
Stefan Monnier <=
- [elpa] externals/setup 3d745d8 15/17: Update info node link, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 36b5ef2 04/17: Add yasnippet configuration as another example, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 761e2ea 05/17: Print signature with princ instead of prin1, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 23e8eef 08/17: Fix syntax-error while defining :with-map, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 6d84649 17/17: Update copyright notice, Stefan Monnier, 2021/03/13
- [elpa] externals/setup 0e95ccd 13/17: Document :repeatable property, Stefan Monnier, 2021/03/13