[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