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

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

[elpa] externals/denote 2f47d31b71 2/5: feat: denote-modules & new modul


From: ELPA Syncer
Subject: [elpa] externals/denote 2f47d31b71 2/5: feat: denote-modules & new module for ffap integration
Date: Wed, 30 Nov 2022 01:57:36 -0500 (EST)

branch: externals/denote
commit 2f47d31b71be23569dfadc178387275f779992c0
Author: Noboru Ota <me@nobiot.com>
Commit: Protesilaos Stavrou <info@protesilaos.com>

    feat: denote-modules & new module for ffap integration
    
    As discussed in Mailing list:
    
    https://lists.sr.ht/~protesilaos/denote/%3C86a64ooxyi.fsf%40nobiot.com%3E
    
    A new module concept is now implemented together with global/minor mode.
    Briefly, they work this way:
    
    1. Set 'denote-modules' by selecting the modules you wish to use
    2. Activate the minor mode globally or locally
    3. This then disables the modules previously enabled, and enable the
       ones newly set -- if it is the first time after Emacs launch, it will
       just enable the modules.
    
    The integration previously available with package and xref are now added
    as separate modules.  A new one with ffap (find-file-at-point) is also
    now added.
    
    * denote.el
    
    (denote-get-relative-path-by-id):
    A new function to return relative filename by identifier.  Currently used
    by the ffap module.
    
    (ffap-next-regexp)(ffap-alist):
    'defvar' to placate compilers
    
    (denote-module-ffap-last-enabled)
    (denote-module-ffap-disable)
    (denote-module-ffap-enable):
    Module for ffap, find-file-at-point, and a helper-var
    
    (denote-modules-last-enabled)
    (denote-modules-disable)
    (denote-modules-enable):
    Function pair to enable/disable modules and helper-var selected with
    'denote-modules'
    
    (denote-modules-mode):
    local minor mode to enable/disable 'denote-modules'
    
    (denote-modules-global-mode):
    global minor to enable/disable 'denote-modules'
    
    (denote-modules-set):
    Setter function for 'denote-modules'
    
    (denote-modules):
    The modules selection to be enabled/disabled
---
 denote.el | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 165 insertions(+)

diff --git a/denote.el b/denote.el
index a24657101d..ca5ad2e8f0 100644
--- a/denote.el
+++ b/denote.el
@@ -709,6 +709,11 @@ whatever matches `denote-excluded-directories-regexp'."
   'denote-get-path-by-id
   "1.0.0")
 
+(defun denote-get-relative-path-by-id (id &optional directory)
+  "Return relative path of ID string in `denote-directory-files'.
+The path is relative to DIRECTORY (default: ‘default-directory’)."
+  (file-relative-name (denote-get-path-by-id id) directory))
+
 (defun denote-directory-files-matching-regexp (regexp)
   "Return list of files matching REGEXP in `denote-directory-files'."
   (seq-filter
@@ -3161,6 +3166,166 @@ Consult the manual for template samples."
 (make-obsolete 'denote-migrate-old-org-filetags nil "1.1.0")
 (make-obsolete 'denote-migrate-old-markdown-yaml-tags nil "1.1.0")
 
+;;; Denote extension "modules"
+
+(defvar denote-module-ffap-last-enabled nil)
+(defvar denote-modules-last-enabled nil)
+;; defvars to placate the compilers
+(defvar denote-modules)
+(defvar ffap-next-regexp)
+(defvar ffap-alist)
+
+(defun denote-module-ffap-disable (&optional local)
+  "Tear down `denote' integration with `ffap'.
+This function is meant to be set as a pair function with
+`denote-module-ffap-enable' in `denote-modules'.
+
+When LOCAL is non-nil, tear down only for the local buffer as
+much as possible.  Currently, `'ffap-alist' is only teared down
+globally."
+  (require 'ffap)
+  (setq ffap-alist (rassq-delete-all  #'denote-get-relative-path-by-id 
ffap-alist))
+  (if local
+      (when denote-module-ffap-last-enabled
+        (setq-local ffap-next-regexp denote-module-ffap-last-enabled))
+    ;; Reset `ffap-next-regexp' only when there is last-active.  Nil
+    ;; means it is in the loading process of denote
+    (when denote-module-ffap-last-enabled
+      (setq ffap-next-regexp denote-module-ffap-last-enabled))))
+
+(defun denote-module-ffap-enable (&optional local)
+  "Set up `denote' integration with `ffap'.
+This function is meant to be set as a pair function with
+`denote-module-ffap-disable' in `denote-modules'.
+
+When LOCAL is non-nil, set up only for the local buffer as much
+as possible.  Currently, `'ffap-alist' is only set globally."
+  (require 'ffap)
+  (if local (setq-local denote-module-ffap-last-active ffap-next-regexp)
+    (setq denote-module-ffap-last-enabled ffap-next-regexp)
+    (add-to-list 'ffap-alist (cons denote-id-regexp 
#'denote-get-relative-path-by-id)))
+  (if local
+      (setq-local ffap-next-regexp (concat ffap-next-regexp "\\|" 
denote-id-regexp))
+    (setq ffap-next-regexp (concat ffap-next-regexp "\\|" denote-id-regexp))))
+
+(defun denote-modules-disable (modules &optional local)
+  "Disable MODULES.
+This function is meant to be used by `denote-modules-enable',
+which calls this function with `denote-modules-last-enable' as
+MODULES to undo the modules currently active.
+
+When LOCAL is non-nil, disable MODULES locally, where possible.
+
+Refer to the document string of `denote-modules-enable' for
+detail."
+  (dolist (pair modules)
+    (let ((hook (car pair))
+          (func (cdr pair)))
+      ;; If HOOK is a function, it's a setup function and FUNC is its
+      ;; teardown counterpart.
+      (if (functionp hook) (funcall func local)
+        (remove-hook hook func local)))))
+
+(defun denote-modules-enable (modules &optional local)
+  "Enable MODULES set by `denote-modules'.
+When LOCAL is non-nil, it tries to enable them only locally.
+Whether this is possible or not depends on the module in
+question.
+
+Each module is defined as a cons sell of either of the following
+forms:
+
+    \(HOOK . FUNCTION\)
+    \(FUNCTION . FUNCTION\)
+
+When a HOOK-FUNCTION pair is defined, `denote-modules-enable'
+function will add FUNCTION to HOOK and `denote-modules-disable'
+function will remove FUNCTION from HOOK.  Generally, it should be
+possible to set HOOK-FUNCTION modules locally.
+
+When a FUNCTION-FUNCTION pair is defined, the first FUNCTION must
+be an enable function and the second, its corresponding disable
+function to undo the former.  They are both called with no
+arguments.  For FUNCTION-FUNCTION modules, in some cases, it may
+not be possible to enable a module locally.  In these cases, some
+parts of a module may be globally set even when LOCAL is non-nil.
+
+NOTES for future development to add new modules
+
+It is important that FUNCTION must be defined and loaded before
+`denote-modules-enable' and `denote-moduel-disable' (the new
+functions should probably written in the source code lines before
+these enable/disable functions) `denote-modules' is cons list of
+the form \(HOOK . FUNCTION\)."
+  (denote-modules-disable denote-modules-last-enabled)
+  (dolist (pair modules)
+    (let ((hook (car pair))
+          (func (cdr pair)))
+      ;; If HOOK is a function, it's a setup function and FUNC is its
+      ;; teardown counterpart.
+      (if (functionp hook) (funcall hook local)
+        (add-hook hook func nil local))))
+  (if local (setq denote-modules-last-enabled modules)
+    (setq denote-modules-last-enabled modules)))
+
+;;;###autoload
+(define-minor-mode denote-modules-mode
+  "Enable donote's extension modules locally."
+  :global nil
+  :init-value nil
+  (if denote-modules-mode
+      (denote-modules-enable denote-modules :local)
+    (denote-modules-disable denote-modules-last-enabled :local)))
+
+;;;###autoload
+(define-minor-mode denote-modules-global-mode
+  "Enable denote's extension modules globally."
+  :global t
+  :init-value nil
+  (if denote-modules-global-mode
+      (denote-modules-enable denote-modules)
+    (denote-modules-disable denote-modules-last-enabled)))
+
+(defun denote-modules-set (symbol value)
+  "Set SYMBOL and VALUE for `denote-modules'.
+Enable the modules set when `denote-modules-mode' or
+`denote-modules-global-mode' is active.  If not, this function
+does not enable them automatically.  Manually call the minor mode
+globally or locally or set it in your configuration.
+
+It is meant to be used `defcustom' of `denote-modules', thus when
+the minor mode is active, changing the modules in the `customize'
+UI will be effective immediately."
+  (set symbol value)
+  (when (or denote-modules-global-mode denote-modules-mode)
+    (denote-modules-enable value)))
+
+(defcustom denote-modules nil
+  "Indicate which modules is to be enabled or disabled.
+These modules are `denote' integration with other Emacs built-in
+features.
+
+When customized in `customize' UI, it presents a set of
+tickboxes, each box represetns an integration module.
+
+Modules are automatically enabled only when either
+`denote-modules-mode' or `denote-modules-global-mode' is active.
+If not, setting the modules does not enable or disable them
+automatically.  Manually call the minor mode globally or locally
+or set it in your configuration."
+  :group 'denote
+  :set #'denote-modules-set
+  :package-version '(denote . "1.2.0")
+  :type
+  '(set (cons :tag "Project integration"
+              (const project-find-functions)
+              (function denote-project-find))
+        (cons :tag "Xref integration"
+              (const xref-backend-functions)
+              (function denote--xref-backend))
+        (cons :tag "Integration with find-file-at-point `ffap'"
+              (function denote-module-ffap-setup)
+              (function denote-module-ffap-teardown))))
 
 ;;;; project.el integration
 ;;   This is also used by xref integration



reply via email to

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