[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/org-superstar 02497248a9 007/162: Adding first revision of
From: |
Stefan Kangas |
Subject: |
[nongnu] elpa/org-superstar 02497248a9 007/162: Adding first revision of org-superstar.el |
Date: |
Fri, 31 Dec 2021 19:35:18 -0500 (EST) |
branch: elpa/org-superstar
commit 02497248a9a8ff9bb683728f9cf178879636eb24
Author: D. Williams <d.williams@posteo.net>
Commit: D. Williams <d.williams@posteo.net>
Adding first revision of org-superstar.el
---
org-superstar.el | 437 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 437 insertions(+)
diff --git a/org-superstar.el b/org-superstar.el
new file mode 100644
index 0000000000..fa86bbb9f1
--- /dev/null
+++ b/org-superstar.el
@@ -0,0 +1,437 @@
+;;; org-superstar.el --- Prettify headings and plain lists in org-mode -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2020 D. Williams, sabof
+
+;; Author: D. Williams <d.williams@posteo.net>
+;; Maintainer: D. Williams <d.williams@posteo.net>
+;; Keywords: faces, outlines, org
+;; Version: 0.0.8
+;; Homepage: None
+
+;; This file is NOT part of GNU Emacs.
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; *IMPORTANT*: This package is under construction. I am still
+;; working out the kinks. Any function and variable defined here is
+;; subject to change until version 1.0.0, from which point on I will
+;; try my best not to inconvenience people.
+
+;; Here are some Unicode blocks which are generally nifty resources
+;; for this package:
+;;
+;; General Punctuation (U+2000-U+206F): bullets, leaders, asterisms
+;; Dingbats (U+2700-U+27BF)
+;; Miscellaneous Symbols and Arrows (U+2B00-U+2BFF)
+
+;;; Code:
+
+(defgroup org-superstar nil
+ "Use UTF8 bullets for headlines and plain lists."
+ :group 'org-appearance)
+
+;;; Bullet Variables
+
+(defcustom org-sstar-headline-bullets-list
+ '(;; Original ones nicked from org-bullets
+ "◉"
+ "○"
+ "✸"
+ "✿")
+ "List of bullets used in Org headings.
+It can contain any number of bullets, the Nth entry usually
+corresponding to the bullet used for level N. The way this list
+is cycled through can use fine-tuned by customizing
+‘org-sstar-cycle-headline-bullets’.
+
+You should restart ‘org-superstar-mode’ after changing this
+variable for your changes to take effect."
+ :group 'org-superstar
+ :type '(repeat (string :tag "Bullet character")))
+
+(defcustom org-sstar-item-bullet-alist
+ '((?* . ?•)
+ (?+ . ?➤)
+ (?- . ?–))
+ "Alist of UTF-8 bullets to be used for plain org lists.
+Each key should be a plain list bullet character (*,+,-), and
+each value should be the UTF8 character to be displayed.
+
+You should restart ‘org-superstar-mode’ after changing this
+variable for your changes to take effect."
+ :group 'org-superstar
+ :type '(alist :options ((?* (character))
+ (?+ (character))
+ (?- (character)))))
+
+;;;###autoload
+(put 'org-sstar-leading-bullet
+ 'safe-local-variable
+ #'char-or-string-p)
+
+(defcustom org-sstar-leading-bullet " ․"
+ "A special bullet used for leading stars.
+Normally, this variable is a character replacing the default
+stars. If it’s a string, list, or vector, compose the
+replacement according to the rules of ‘compose-region’ for the
+COMPONENTS argument.
+
+If ‘org-hide-leading-stars’ is nil, leading stars in a headline
+are represented as a sequence of this bullet using the face
+‘org-sstar-leading’. Otherwise, this variable has no effect and
+‘org-mode’ covers leading stars using ‘org-hide’.
+
+You should restart ‘org-superstar-mode’ after changing this
+variable for your changes to take effect."
+ :group 'org-superstar
+ :type '(choice
+ (character :tag "Single character to display"
+ :format "\n%t: %v\n"
+ :value ?‥)
+ (string :tag "String of characters to compose replacement from"
+ :format "\n%t:\n%v"
+ :value " ․")
+ (vector :tag "Vector of chars and composition rules"
+ (repeat
+ :inline t
+ :tag "Composition sequence"
+ (list :inline t :tag "Composition pair"
+ (character :tag "alt char" :value ?\s)
+ (sexp :tag "rule"))))
+ (repeat
+ :tag "Sequence of chars and composition rules"
+ (list :inline t :tag "Composition pair"
+ (character :tag "alt char" :value ?\s)
+ (sexp :tag "rule"))))
+ :risky t)
+
+
+;;; Other Custom Variables
+
+(defcustom org-sstar-prettify-leading-stars t
+ "If nil, keep leading stars in headlines unchanged.
+It is a good idea to disable this feature when you run into any
+peformance issues because of this package. You can still hide
+leading stars using ‘org-hide-leading-stars’.
+
+You should restart ‘org-superstar-mode’ after changing this
+variable for your changes to take effect."
+ :group 'org-superstar
+ :type '(choice
+ (const :tag "Prettify leading stars." t)
+ (const :tag "Don’t prettify leading stars." nil)))
+
+(defcustom org-sstar-cycle-headline-bullets t
+ "Non-nil means headline bullets cycle through
‘org-sstar-headline-bullets-list’.
+
+The following values are meaningful:
+
+An integer value of N cycles through the first N entries of the
+list instead of the whole list.
+
+If otherwise non-nil, cycle through the entirety of the list.
+This is the default behavior inherited from org-bullets.
+
+If nil, repeat the final list entry for all successive levels.
+
+You should restart ‘org-superstar-mode’ after changing this
+variable for your changes to take effect."
+ :group 'org-superstar
+ :type '(choice
+ (const :tag "Cycle through the whole list." t)
+ (const :tag "Repeat the last element indefinitely." nil)
+ (integer :tag "Repeat the first <integer> elements only."
+ :format "Repeat the first %v entries exclusively.\n"
+ :size 8
+ :value 1
+ :validate org-sstar--validate-hcycle)))
+
+(defun org-sstar--validate-hcycle (text-field)
+ "Validate integer values of ‘org-sstar-cycle-headline-bullets’ in TEXT-FIELD.
+If the integer exceeds the length of ‘org-sstar-headline-bullets-list’,
+set it to the length and raise an error."
+ (let ((ncycle (widget-value text-field))
+ (maxcycle (org-sstar--hbullets)))
+ (unless (<= 1 ncycle maxcycle)
+ (widget-put
+ text-field
+ :error (format "Value must be between 1 and %i"
+ maxcycle))
+ (widget-value-set text-field maxcycle)
+ text-field)))
+
+(defcustom org-sstar-prettify-item-bullets t
+ "If non-nil, display plain lists bullets as UTF8 bullets.
+
+Each type of plain list bullet is associated with a
+corresponding UTF8 character in ‘org-sstar-item-bullet-alist’.
+
+You should restart ‘org-superstar-mode’ after changing this
+variable for your changes to take effect."
+ :group 'org-superstar
+ :type '(choice (const :tag "Enable item bullet fontification" t)
+ (const :tag "Disable item bullet fontification" nil)))
+
+
+;;; Faces
+
+(defface org-sstar-leading
+ '((default . (:inherit default :foreground "gray")))
+ "Face used to display prettified leading stars in a headline."
+ :group 'org-superstar)
+
+(defface org-sstar-header-bullet
+ '((default . nil))
+ "Face containing distinguishing features headline bullets.
+This face is applied to header bullets \"on top of\" existing
+fontification provided by org, allowing you to inherit the
+default look of a heading line while still being able to make
+modifications. Every specified face property will replace those
+currently in place. Consequently, leaving all face properties
+unspecified causes bullets to inherit the org-level-X faces."
+ :group 'org-superstar)
+
+(defface org-sstar-item
+ '((default . (:inherit default)))
+ "Face used to display prettified item bullets."
+ :group 'org-superstar)
+
+;;; Functions
+
+(defun org-sstar-configure-like-org-bullets ()
+ "Configure ‘org-superstar-mode’ to approximate ‘org-bullets-mode’.
+This function automatically sets various custom variables, and
+therefore should only be called *once* per session, before any
+other manual customization of this package.
+
+Warning: This function sets a variable outside of this package:
+‘org-hide-leading-stars’.
+
+This function is only meant as a small convenience for people who
+just want minor depatures from ‘org-bullets-mode’. For a more
+fine-grained customization, it’s better to just set the variables
+you want.
+
+This changes the following variables:
+‘org-sstar-prettify-leading-stars’: Disabled.
+‘org-sstar-prettify-leading-stars’: Disabled.
+‘org-sstar-cycle-headline-bullets’: Enabled.
+‘org-hide-leading-stars’: Enabled.
+
+You should restart ‘org-superstar-mode’ after calling this
+function for your changes to take effect."
+ (setq org-sstar-prettify-leading-stars nil)
+ (setq org-sstar-cycle-headline-bullets t)
+ (setq org-hide-leading-stars t)
+ nil)
+
+;;; Accessor Functions
+
+(defun org-sstar--hbullets ()
+ "Return the length of ‘org-sstar-headline-bullets-list’."
+ (length org-sstar-headline-bullets-list))
+
+(defun org-sstar--hbullet (level)
+ "Return the desired headline bullet replacement for level N.
+
+See also ‘org-sstar-cycle-headline-bullets’."
+ (let ((max-bullets org-sstar-cycle-headline-bullets)
+ (n (1- level)))
+ (string-to-char
+ (cond ((integerp max-bullets)
+ (elt org-sstar-headline-bullets-list
+ (% n max-bullets)))
+ (max-bullets
+ (elt org-sstar-headline-bullets-list
+ (% n (org-sstar--hbullets))))
+ (t
+ (elt org-sstar-headline-bullets-list
+ (min n (1- (org-sstar--hbullets)))))))))
+
+(defun org-sstar--ibullet (bullet-string)
+ "Return BULLET-STRINGs desired UTF-8 replacement.
+
+Each of the three regular plain list bullets +, - and * will be
+replaced by their corresponding entry in ‘org-sstar-item-bullet-alist’."
+ (or (cdr (assq (string-to-char bullet-string)
+ org-sstar-item-bullet-alist))
+ (string-to-char bullet-string)))
+
+;;; Fontification
+
+(defun org-sstar--prettify-ibullets ()
+ "Prettify plain list bullets.
+
+This function uses ‘org-list-in-valid-context-p’ to avoid
+prettifying bullets in (for example) source blocks."
+ (when (org-list-in-valid-context-p)
+ (let* ((current-bullet (match-string 1)))
+ (compose-region (match-beginning 1)
+ (match-end 1)
+ (org-sstar--ibullet current-bullet)))
+
+ 'org-sstar-item))
+
+(defun org-sstar--unprettify-ibullets ()
+ "Revert all changes made to item bullets."
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]+\\([-+*]\\) " nil t)
+ (decompose-region (match-beginning 1) (match-end 1)))))
+
+
+(defun org-sstar--prettify-main-hbullet ()
+ "Prettify the trailing star in a headline.
+
+This function uses ‘org-list-in-valid-context-p’ to avoid
+prettifying bullets in (for example) source blocks."
+ (when (org-list-in-valid-context-p)
+ (let ((level (- (match-end 0) (match-beginning 0) 1)))
+ (compose-region (match-beginning 1) (match-end 1)
+ (org-sstar--hbullet level))))
+ 'org-sstar-header-bullet)
+
+(defun org-sstar--prettify-other-hbullet ()
+ "Prettify the second last star in a headline.
+This is only done if the particular title’s level is part of an
+inline task, see ‘org-inlinetask-min-level’. Otherwise, this
+block is formatted like the leading asterisks, see
+‘org-sstar--prettify-leading-hbullets’.
+
+This function uses ‘org-list-in-valid-context-p’ to avoid
+prettifying bullets in (for example) source blocks."
+ (when (org-list-in-valid-context-p)
+ (let* ((level (- (match-end 0) (match-beginning 0) 1))
+ (is-inline-task
+ (and (boundp 'org-inlinetask-min-level)
+ (>= level org-inlinetask-min-level)))
+ (compose-star (or is-inline-task
+ (and (not org-hide-leading-stars)
+ org-sstar-prettify-leading-stars)))
+ (bullet-char (if is-inline-task
+ (org-sstar--hbullet level)
+ org-sstar-leading-bullet)))
+ (when compose-star
+ (compose-region (match-beginning 2) (match-end 2)
+ bullet-char))
+ (cond (is-inline-task 'org-sstar-header-bullet)
+ (org-sstar-prettify-leading-stars 'org-sstar-leading)
+ (t 'custom-invalid)))))
+
+;; (defun org-sstar--prettify-leading-hbullets ()
+;; "Prettify the leading bullets of a header line.
+;; Unless ‘org-hide-leading-stars’ is non-nil, each leading star is
+;; visually replaced by ‘org-sstar-leading-bullet-char’ and inherits
+;; face properties from ‘org-sstar-leading’.
+
+;; This function uses ‘org-list-in-valid-context-p’ to avoid
+;; prettifying bullets in (for example) source blocks."
+;; (when (org-list-in-valid-context-p)
+;; (let* ((match-len (- (match-end 3) (match-beginning 3)))
+;; ;;(level (- (match-end 0) (match-beginning 0) 1))
+;; ;; (is-inline-task
+;; ;; (and (boundp 'org-inlinetask-min-level)
+;; ;; (>= level org-inlinetask-min-level)))
+;; )
+;; (unless org-hide-leading-stars
+;; (let ((star-beg (match-beginning 3))
+;; (star-end (1+ (match-beginning 3))))
+;; (dotimes (i match-len 'org-sstar-leading)
+;; (compose-region (+ star-beg i) (+ star-end i)
+;; org-sstar-leading-bullet)))))))
+
+
+(defun org-sstar--prettify-leading-hbullets ()
+ "Prettify the leading bullets of a header line.
+Unless ‘org-hide-leading-stars’ is non-nil, each leading star is
+visually replaced by ‘org-sstar-leading-bullet-char’ and inherits
+face properties from ‘org-sstar-leading’.
+
+This function uses ‘org-list-in-valid-context-p’ to avoid
+prettifying bullets in (for example) source blocks."
+ (when (org-list-in-valid-context-p)
+ (unless org-hide-leading-stars
+ (let ((star-beg (match-beginning 3))
+ (lead-end (match-end 3)))
+ (while (< star-beg lead-end)
+ (compose-region star-beg (setq star-beg (1+ star-beg))
+ org-sstar-leading-bullet))
+ 'org-sstar-leading))))
+
+
+
+(defun org-sstar--unprettify-hbullets ()
+ "Revert all changes made to header bullets."
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^\\*+ " nil t)
+ (decompose-region (match-beginning 0) (match-end 0)))))
+
+;;; Font Lock
+
+(defvar-local org-sstar--font-lock-keywords nil)
+
+(defun org-sstar--update-font-lock-keywords ()
+ "Set ‘org-sstar--font-lock-keywords’ to reflect current settings.
+You should not call this function to avoid confusing the cleanup
+routines of ‘org-superstar-mode’."
+ ;; The below regex is nicked from ‘org-list-full-item-re’, but
+ ;; reduced to only match simple lists. Replaced [ \t]* by [ \t]+ to
+ ;; avoid confusion with title bullets.
+ (setq org-sstar--font-lock-keywords
+ `(,@(when org-sstar-prettify-item-bullets
+ '(("^[ \t]+\\([-+*]\\) "
+ (1 (org-sstar--prettify-ibullets)))))
+ ("^\\(?3:\\**?\\)\\(?2:\\*?\\)\\(?1:\\*\\) "
+ (1 (org-sstar--prettify-main-hbullet) prepend)
+ ,@(when org-sstar-prettify-leading-stars
+ '((3 (org-sstar--prettify-leading-hbullets)
+ t)))
+ (2 (org-sstar--prettify-other-hbullet) prepend))
+ ;; If requested, put another function here that formats the
+ ;; first two stars of an inline as a bullet.
+ )))
+
+(defun org-sstar--fontify-buffer ()
+ (when font-lock-mode
+ (if (and (fboundp 'font-lock-flush)
+ (fboundp 'font-lock-ensure))
+ (save-restriction
+ (widen)
+ (font-lock-ensure)
+ (font-lock-flush)))))
+
+;;;###autoload
+(define-minor-mode org-superstar-mode
+ "Use UTF8 bullets for headlines and plain lists."
+ nil " ✨" nil
+ :group 'org-superstar
+ :require 'org
+ (cond
+ (org-superstar-mode
+ (org-sstar--update-font-lock-keywords)
+ (font-lock-add-keywords nil org-sstar--font-lock-keywords
+ 'append)
+ (org-sstar--fontify-buffer))
+ (t
+ (font-lock-remove-keywords nil org-sstar--font-lock-keywords)
+ (org-sstar--unprettify-ibullets)
+ (org-sstar--unprettify-hbullets)
+ (org-sstar--fontify-buffer))
+ ))
+
+(provide 'org-superstar)
+;;; org-superstar.el ends here
- [nongnu] elpa/org-superstar 98bba637cd 078/162: removing old bullet point, (continued)
- [nongnu] elpa/org-superstar 98bba637cd 078/162: removing old bullet point, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 22a44f14ee 026/162: overhauled testing module composure-test.el, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 589b136106 064/162: updating homepage., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar a0d2cfaae1 076/162: "org-mode" -> "Org mode", Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 4500a774bb 068/162: Added an FAQ., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar a078ca392a 079/162: Remove unnecessary lighter for Org Superstar., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 369292856e 042/162: reduced minimal-setup, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 3818dff655 006/162: Completed first draft of README., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 3bbb8e551c 011/162: updating gitignore to correctly handle temp files, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar d9accdcad7 002/162: Added README, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 02497248a9 007/162: Adding first revision of org-superstar.el,
Stefan Kangas <=
- [nongnu] elpa/org-superstar d45e1eb060 004/162: Added further fix: forgot that ‘’-support was a custom modification., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 3f29ff9cba 010/162: added disclaimer, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 8fd1d05c6c 013/162: Added wrapper around org-list-in-valid-context-p for refinement purposes, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 54811604be 012/162: adding new sample image, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 070360a2d2 009/162: Formatting changes to adhere more closely to coding conventions., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 6143af17ed 015/162: updating .gitignore to skip .dir-locals.el, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar b72da86641 014/162: added image to README, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 59391390df 056/162: Added support for making leading stars invisible., Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar 7e2ca95932 033/162: added new, more modular sample inputs for incoming unit testing, Stefan Kangas, 2021/12/31
- [nongnu] elpa/org-superstar d6071eb477 071/162: Updating README to fit first major version (1.0.0), Stefan Kangas, 2021/12/31