emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] scratch/hook-helpers 93ae501 12/19: Finished last commit.


From: Ian Dunn
Subject: [elpa] scratch/hook-helpers 93ae501 12/19: Finished last commit.
Date: Sun, 23 Apr 2017 12:50:40 -0400 (EDT)

branch: scratch/hook-helpers
commit 93ae501db07671d7ae08b1b7b4700212303549b7
Author: Ian Dunn <address@hidden>
Commit: Ian Dunn <address@hidden>

    Finished last commit.
---
 README.org            | 95 +++++++++++++++++++++++++++------------------------
 hook-helpers-tests.el | 92 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+), 44 deletions(-)

diff --git a/README.org b/README.org
index 9da1813..2af2a8e 100644
--- a/README.org
+++ b/README.org
@@ -3,7 +3,7 @@
 #+EMAIL: address@hidden
 
 * Copying
-Copyright (C) 2016 Ian Dunn
+Copyright (C) 2016-2017 Ian Dunn
 
 #+BEGIN_QUOTE
 This program is free software: you can redistribute it and/or modify
@@ -28,13 +28,13 @@ they don’t do this, then it will be an anonymous function.  
If the anonymous
 function is modified, then the function can’t be removed.  With a function
 outside of the ~add-hook~ call, it looks messy.
 
-The ~define-hook-helper~ macro is a solution to this.  Think of it as an
-anaphoric ~add-hook~, but one that can be called many times without risking
-redundant hook functions.  It gives a cleaner look and feel to Emacs
-configuration files, and could even be used in actual libraries.
+Hook Helpers are a solution to this.  A "hook helper" is an anonymous,
+modifiable function created for the sole purpose of being attached to a hook.
+This combines the two commonly used methods mentioned above.  The functions
+don't exist, so they don't get in the way of ~C-h f~, but they can be removed 
or
+modified as needed.
 
-The purpose of this package is to build upon add-hook and remove-hook.  When 
you
-have something like the following:
+Let's look at an example:
 
 #+BEGIN_SRC emacs-lisp
 (defun my/after-init-hook ()
@@ -64,57 +64,64 @@ Which handles everything for you.
 
 * Usage
 
-Under the hood, ~define-hook-helper~ creates a new function, called
-~hook-helper--HOOK~.
+There are two macros in hook helpers: ~define-hook-helper~ and 
~create-hook-helper~.
+
+The former is a basic case; it creates and adds a helper for a single hook.
+Most hooks have the -hook suffix, so we take advantage of that here for a 
little
+less typing.  In order to add a helper to a non-standard hook, use the 
~:suffix~
+argument:
 
 #+BEGIN_SRC emacs-lisp
-(define-hook-helper after-init ()
-  (set-scroll-bar-mode nil))
+(define-hook-helper my ()
+  :suffix function
+  :append t
+  (message "Hello!"))
 #+END_SRC
 
-The above creates the function ‘hook-helper--after-init’.
+We also introduce the ~:append~ keyword above, which does exactly what it 
sounds
+like.
 
-** "But doesn't that mean I can only use this once per hook?"
+There's one more keyword for ~define-hook-helper~: ~:name~.  This specifies an
+additional name for the new helper.  Without this, its helper ID is just the
+name of the hook; with a ~:name~, its ID is HOOK-NAME/NAME.
 
-I thought about that too, and devised a solution.  ~define-hook-helper~ accepts
-several keywords: name, suffix, and append.  Append does exactly what it says 
on
-the tin: It appends the hook, passing the argument straight to ~add-hook~.
-
-Name tacks a name onto the defined hook function.  For instance, take the
-previous example:
+The work horse of hook helpers is ~create-hook-helper~.  This is the generic 
case,
+capable of adding itself to any number of hooks:
 
 #+BEGIN_SRC emacs-lisp
-(define-hook-helper after-init ()
-  :name env
-  (set-scroll-bar-mode nil))
+(create-hook-helper new-helper ()
+  :hooks (hook-1-hook
+          (hook-2-hook . t)
+          hook-3-function)
+  (message "Look at all that we can do!"))
 #+END_SRC
 
-This creates the function =hook-helper--after-init/env=, thus allowing
-anyone to use ~define-hook-helper~ as many times as they like, without fear
-of name clobbering.
+This creates a new hook helper called "new-helper", and adds it to 
~hook-1-hook~,
+~hook-2-hook~, and ~hook-3-function~, appending to the latter.
 
-Arguments to the new function may also be specified.  Let's say you've got a
-hook like so:
+The ~:hooks~ keyword can have the following form:
 
-#+BEGIN_SRC emacs-lisp
-(define-hook-helper after-make-frame (frame)
-  :suffix "functions"
-  (set-frame-parameter frame 'alpha '(90 50)))
-#+END_SRC
+- A single hook
+- A cons cell (HOOK . APPEND)
+- A list containing a mixture of the above two forms
 
-Also note the ~suffix~ keyword.  This tells ~define-hook-helper~ to add the
-helper to the variable ~after-make-frame-functions~ instead of
-~after-make-frame-hook~.  The arguments tells it to create a function with
-one argument, ~frame~.
+This is called a "hook spec".
 
-** Removing the Function
-To remove the new function from the hook, you can use the function
-~remove-hook-helper~.  It works just as ~define-hook-helper~:
+** Adding and Removing Helpers
+To add or remove helpers, the functions add-hook-helper and remove-hook-helper
+are provided.
 
 #+BEGIN_SRC emacs-lisp
-(remove-hook-helper text-mode)
-(remove-hook-helper after-init
-  :name env)
-(remove-hook-helper after-make-frame
-  :suffix "functions")
+(add-hook-helper 'test-helper '(hook-the-first hook-the-second))
+(remove-hook-helper 'test-helper 'hook-the-second)
 #+END_SRC
+
+As you can see, each of them takes the same arguments: a symbol denoting the
+helper to add or remove, and a quoted hook spec.
+
+** Seeing all the Available Helpers
+
+Seeing lambda functions in your hooks can be confusing.  While we don't have a
+solution for that, we do have ~describe-hook-helpers~, an interactive function
+that creates a pretty buffer containing all the defined hook helpers, grouped 
by
+the hooks to which they are attached.
diff --git a/hook-helpers-tests.el b/hook-helpers-tests.el
new file mode 100644
index 0000000..9d732fc
--- /dev/null
+++ b/hook-helpers-tests.el
@@ -0,0 +1,92 @@
+;;; hook-helpers-tests.el --- Tests for hook helpers
+
+;; Copyright (C) 2016,2017 Ian Dunn
+
+;; Author: Ian Dunn <address@hidden>
+;; Keywords: development, hooks
+;; URL: https://savannah.nongnu.org/projects/hook-helpers-el/
+;; Version: 1.0
+
+;; 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:
+
+;;; Code:
+
+(require 'hook-helpers)
+(require 'ert)
+
+(ert-deftest hkhlp-normalize-hook-spec-test ()
+  (should (equal (hkhlp-normalize-hook-spec 'c++-mode-hook)
+                 '((c++-mode-hook))))
+  (should (equal (hkhlp-normalize-hook-spec '(c++-mode-hook . t))
+                 '((c++-mode-hook . t))))
+  (should (equal (hkhlp-normalize-hook-spec '(c++-mode-hook org-mode-hook))
+                 '((c++-mode-hook) (org-mode-hook))))
+  (should (equal (hkhlp-normalize-hook-spec '((c++-mode-hook . t) 
org-mode-hook))
+                 '((c++-mode-hook . t) (org-mode-hook))))
+  (should (equal (hkhlp-normalize-hook-spec '(c++-mode-hook (org-mode-hook . 
t)))
+                 '((c++-mode-hook) (org-mode-hook . t))))
+  (should (equal (hkhlp-normalize-hook-spec '((c++-mode-hook . t)
+                                              (org-mode-hook . t)))
+                 '((c++-mode-hook . t) (org-mode-hook . t)))))
+
+(ert-deftest hkhlp-create-hook-helper-test ()
+  (let ((test-hook nil))
+    (create-hook-helper test-helper ()
+      "Test Hook Helper"
+      :hooks (test-hook)
+      (message "This is a test"))
+    (should (equal test-hook (list
+                              (lambda () "Test Hook Helper" (message "This is 
a test")))))))
+
+(ert-deftest hkhlp-add-hook-helper ()
+  (let ((test-hook nil)
+        (test-2-hook nil))
+    (create-hook-helper test-helper ()
+      "Test Hook Helper"
+      :hooks (test-hook)
+      (message "This is a test"))
+    (should (equal test-hook (list
+                              (lambda () "Test Hook Helper" (message "This is 
a test")))))
+    (add-hook-helper 'test-helper '(test-2-hook))
+    (should (equal test-2-hook test-hook))))
+
+(ert-deftest hkhlp-remove-hook-helper ()
+  (let ((test-hook nil))
+    (create-hook-helper test-helper ()
+      "Test Hook Helper"
+      :hooks (test-hook)
+      (message "This is a test"))
+    (should (equal test-hook (list
+                              (lambda () "Test Hook Helper" (message "This is 
a test")))))
+    (remove-hook-helper 'test-helper 'test-hook)
+    (should (equal test-hook nil))))
+
+(ert-deftest hkhlp-update-hook-helper ()
+  (let ((test-hook nil)
+        (old-func (lambda () "Test Hook Helper" (message "This is a test")))
+        (new-func (lambda () "Test Hook Helper" (message "This is another 
test"))))
+    (create-hook-helper test-helper ()
+      "Test Hook Helper"
+      :hooks (test-hook)
+      (message "This is a test"))
+    (should (equal test-hook (list old-func)))
+    (create-hook-helper test-helper ()
+      "Test Hook Helper"
+      :hooks (test-hook)
+      (message "This is another test"))
+    (should (equal test-hook (list new-func)))))
+
+;;; hook-helpers-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]