branch: elpa/casual
commit e1151a66838acfb58b74d9892ab93108f0761c91
Merge: 2d1cfd6fe4 d352a06c1b
Author: Charles Choi <[email protected]>
Commit: GitHub <[email protected]>

    Merge pull request #148 from 
kickingvegas/merge-development-to-main-20250128_114420
    
    Merge development to main 20250128_114420
---
 docs/editkit.org                                   |  76 ++++++++-----
 docs/images/casual-editkit-main-screenshot.png     | Bin 317764 -> 242099 bytes
 docs/images/casual-editkit-narrow-screenshot.png   | Bin 0 -> 97375 bytes
 .../images/casual-editkit-transform-screenshot.png | Bin 154973 -> 127099 bytes
 docs/images/casual-info-screenshot.png             | Bin 344749 -> 447998 bytes
 lisp/casual-editkit-utils.el                       |  40 ++++++-
 lisp/casual-editkit.el                             |   2 +
 lisp/casual-info.el                                |   3 +-
 lisp/casual.el                                     |   2 +-
 tests/test-casual-editkit-utils.el                 | 118 +++++++++++++++++++++
 tests/test-casual-editkit.el                       |  16 ++-
 tests/test-casual-info.el                          |   2 +
 12 files changed, 228 insertions(+), 31 deletions(-)

diff --git a/docs/editkit.org b/docs/editkit.org
index 4bf04b9a1f..675f5fad33 100644
--- a/docs/editkit.org
+++ b/docs/editkit.org
@@ -5,32 +5,40 @@ An opinionated 
[[https://github.com/magit/transient][Transient]]-based user inte
 
 [[file:images/casual-editkit-main-screenshot.png]]
 
-Casual EditKit endeavors to surface the many different editing commands 
offered by Emacs via Transient menus. Included in this library are menus for:
-
-- Register commands
-- Rectangle commands
-- Editing commands for words, sentences, paragraphs, and balanced expressions 
(sexps), and functions (defuns). 
-  - Marking
-  - Copying
-  - Killing
-  - Moving
-  - Transposing
-  - Transforming
-  - Deleting
-  - Sorting
-- Window management
-  - Creating
-  - Moving
-  - Deleting
-- Search & Replace commands
-- Open commands
-- Project commands
-- Bookmark commands
-- Emoji & Symbol Insertion (including smart quotes)
-- Tool commands
-- Macro commands
-
-A main menu (~casual-editkit-main-tmenu~) demonstrating all of the above is 
provided as a reference model. This reference model can be used as is. More 
motivated users can use the reference model as a template to build their own 
customized menus.
+Casual EditKit endeavors to surface the many different editing commands 
offered by Emacs via Transient menus. The main menu 
(~casual-editkit-main-tmenu~) both demonstrates and provides a reference to all 
EditKit menus. Motivated users can customize this menu to their taste.
+
+* Table of Contents                                                   :TOC_3:
+- [[#casual-editkit][Casual EditKit]]
+- [[#motivation][Motivation]]
+  - [[#goals][Goals]]
+  - [[#non-goals][Non-Goals]]
+- [[#install][Install]]
+- [[#library-overview][Library Overview]]
+  - [[#register-commands-casual-editkit-registers-tmenu][Register commands 
(~casual-editkit-registers-tmenu~)]]
+  - [[#rectangle-commands-casual-editkit-rectangle-tmenu][Rectangle commands 
(~casual-editkit-rectangle-tmenu~)]]
+  - [[#edit-commands-casual-editkit-edit-tmenu][Edit commands 
(~casual-editkit-edit-tmenu~)]]
+    - [[#mark-casual-editkit-mark-tmenu][Mark (~casual-editkit-mark-tmenu~)]]
+    - [[#copy-casual-editkit-copy-tmenu][Copy (~casual-editkit-copy-tmenu~)]]
+    - [[#kill-cut-casual-editkit-kill-tmenu][Kill (Cut) 
(~casual-editkit-kill-tmenu~)]]
+    - [[#move-casual-editkit-move-tmenu][Move (~casual-editkit-move-tmenu~)]]
+    - [[#transpose-casual-editkit-transpose-tmenu][Transpose 
(~casual-editkit-transpose-tmenu~)]]
+    - [[#transform-casual-editkit-transform-tmenu][Transform 
(~casual-editkit-transform-tmenu~)]]
+    - [[#delete-casual-editkit-delete-tmenu][Delete 
(~casual-editkit-delete-tmenu~)]]
+    - [[#sort-casual-editkit-sort-tmenu][Sort (~casual-editkit-sort-tmenu~)]]
+    - [[#reformat-casual-editkit-reformat-tmenu][Reformat 
(~casual-editkit-reformat-tmenu~)]]
+  - [[#window-management-casual-editkit-window-tmenu][Window management 
(~casual-editkit-window-tmenu~)]]
+    - [[#deletion-casual-editkit-window-delete-tmenu][Deletion 
(~casual-editkit-window-delete-tmenu~)]]
+  - [[#search--replace-commands-casual-editkit-search-tmenu][Search & Replace 
commands (~casual-editkit-search-tmenu~)]]
+  - [[#open-commands-casual-editkit-open-tmenu][Open commands 
(~casual-editkit-open-tmenu~)]]
+  - [[#project-commands-casual-editkit-project-tmenu][Project commands 
(~casual-editkit-project-tmenu~)]]
+  - [[#bookmark-commands-casual-editkit-bookmarks-tmenu][Bookmark commands 
(~casual-editkit-bookmarks-tmenu~)]]
+  - [[#emoji--symbol-insertion-casual-editkit-emoji-symbol-tmenu][Emoji & 
Symbol Insertion (~casual-editkit-emoji-symbol-tmenu~)]]
+  - [[#tool-commands-casual-editkit-tools-tmenu][Tool commands 
(~casual-editkit-tools-tmenu~)]]
+  - [[#narrowwiden-commands-casual-editkit-narrow-tmenu][Narrow/Widen Commands 
(~casual-editkit-narrow-tmenu~)]]
+  - [[#macro-casual-editkit-macro-tmenu][Macro (~casual-editkit-macro-tmenu~)]]
+  - [[#settings-casual-editkit-settings-tmenu][Settings 
(~casual-editkit-settings-tmenu~)]]
+- [[#sponsorship][Sponsorship]]
+- [[#see-also][See Also]]
 
 * Motivation
 Emacs has many commands that are easy to forget if not used frequently. Menus 
are a user interface (UI) affordance that offers discoverability and 
recognition that can lower its learning curve. While menus are commonly 
associated with mouse-driven UI, the inclusion of Transient in Emacs core 
allows for building a keyboard-driven menu UI. Casual EditKit endeavors to 
offer this as many Emacs users prefer keyboard-driven workflows.
@@ -159,6 +167,22 @@ This menu holds an assorted collection of different 
tools/utilities provided by
 
 [[file:images/casual-editkit-tools-screenshot.png]]
 
+** Narrow/Widen Commands (~casual-editkit-narrow-tmenu~)
+Support for 
[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Narrowing.html][narrowing
 and widening]] a buffer is supported. Mode specific narrowing behavior is 
supported for Org and ~prog-mode~ derived buffers.
+
+[[file:images/casual-editkit-narrow-screenshot.png]]
+
+This menu can be 
[[https://www.gnu.org/software/emacs/manual/html_mono/transient.html#Modifying-Existing-Transients][modified]]
 to support narrowing in other modes, particularly those that are packaged with 
Emacs. For example, if one wanted narrowing support for Markdown 
([[https://jblevins.org/projects/markdown-mode/][markdown-mode]]), the 
following initialization code can be used.
+
+#+begin_src elisp :lexical no
+  (transient-append-suffix 'casual-editkit-narrow-tmenu '(0 0)
+     ["Markdown"
+      :if (lambda () (derived-mode-p 'markdown-mode))
+      ("s" "Subtree" markdown-narrow-to-subtree)
+      ("b" "Block" markdown-narrow-to-block)
+      ("p" "Page" markdown-narrow-to-page)])
+#+end_src
+
 ** Macro (~casual-editkit-macro-tmenu~)
 Commands for managing macros are provided for by this menu. Note that macro 
creation commands are /not/ supported as they are tightly-bound to keybindings. 
 
diff --git a/docs/images/casual-editkit-main-screenshot.png 
b/docs/images/casual-editkit-main-screenshot.png
index 694b7e1b53..a169d9d26a 100644
Binary files a/docs/images/casual-editkit-main-screenshot.png and 
b/docs/images/casual-editkit-main-screenshot.png differ
diff --git a/docs/images/casual-editkit-narrow-screenshot.png 
b/docs/images/casual-editkit-narrow-screenshot.png
new file mode 100644
index 0000000000..6b250444ba
Binary files /dev/null and b/docs/images/casual-editkit-narrow-screenshot.png 
differ
diff --git a/docs/images/casual-editkit-transform-screenshot.png 
b/docs/images/casual-editkit-transform-screenshot.png
index 6afcb98823..225eca9bff 100644
Binary files a/docs/images/casual-editkit-transform-screenshot.png and 
b/docs/images/casual-editkit-transform-screenshot.png differ
diff --git a/docs/images/casual-info-screenshot.png 
b/docs/images/casual-info-screenshot.png
index 8de71f8727..cfeb019e29 100644
Binary files a/docs/images/casual-info-screenshot.png and 
b/docs/images/casual-info-screenshot.png differ
diff --git a/lisp/casual-editkit-utils.el b/lisp/casual-editkit-utils.el
index eb4e1ff13e..8c4fa58937 100644
--- a/lisp/casual-editkit-utils.el
+++ b/lisp/casual-editkit-utils.el
@@ -702,8 +702,12 @@ Commands pertaining to rectangle operations can be 
accessed here."
 
 Commands pertaining to transformation operations can be accessed here."
   ["Transform"
-   [("c" "Capitialize" capitalize-dwim :transient t)
-    ("l" "Make Lower Case" downcase-dwim :transient t)
+   [("c" "Capitalize" capitalize-dwim :transient t)
+    ("t" "Title Region (Upcase Initials)" upcase-initials-region
+     :transient t
+     :inapt-if-not use-region-p)]
+
+   [("l" "Make Lower Case" downcase-dwim :transient t)
     ("u" "Make Upper Case" upcase-dwim :transient t)]
 
    [("RET" "Done" transient-quit-all)]]
@@ -776,6 +780,38 @@ accessed here."
                     (format "Fill Column (%d)" fill-column)))]
   casual-editkit-navigation-group)
 
+;;;###autoload (autoload 'casual-editkit-narrow-tmenu "casual-editkit-utils" 
nil t)
+(transient-define-prefix casual-editkit-narrow-tmenu ()
+  "Menu for narrow commands."
+
+  ["Narrow"
+   ["Programming"
+    ("d" "Defun" narrow-to-defun
+     :if (lambda () (derived-mode-p 'prog-mode)))]
+
+   ["Org"
+    :if (lambda () (derived-mode-p 'org-mode))
+    ("s" "Subtree" org-narrow-to-subtree)
+    ("b" "Block" org-narrow-to-block)
+    ("e" "Element" org-narrow-to-element)]
+
+   ["Region"
+    ("r" "Region" narrow-to-region
+     :inapt-if-not use-region-p)]]
+
+  casual-editkit-navigation-group)
+
+;; !!!
+;; If markdown-mode is installed, then this will add markdown-mode specific
+;; narrowing commands to casual-editkit-narrow-tmenu.
+;;
+;; (transient-append-suffix 'casual-editkit-narrow-tmenu '(0 0)
+;;    ["Markdown"
+;;     :if (lambda () (derived-mode-p 'markdown-mode))
+;;     ("s" "Subtree" markdown-narrow-to-subtree)
+;;     ("b" "Block" markdown-narrow-to-block)
+;;     ("p" "Page" markdown-narrow-to-page)])
+
 ;;; Functions
 (defun casual-editkit-macro-info ()
   "Get Info for syntax of regexps."
diff --git a/lisp/casual-editkit.el b/lisp/casual-editkit.el
index cffa1f80b7..76934e2501 100644
--- a/lisp/casual-editkit.el
+++ b/lisp/casual-editkit.el
@@ -70,6 +70,8 @@ user-customized menu."
     ("C-o" "Open line" open-line
      :transient t
      :if-not casual-editkit-buffer-read-only-p)
+    ("N" "Narrow›" casual-editkit-narrow-tmenu :if-not buffer-narrowed-p)
+    ("W" "Widen" widen :if buffer-narrowed-p)
     ("E" "Emoji & Symbols›" casual-editkit-emoji-symbols-tmenu
      :if-not casual-editkit-buffer-read-only-p)]
 
diff --git a/lisp/casual-info.el b/lisp/casual-info.el
index 610feb4fe1..4a81ed2c1e 100644
--- a/lisp/casual-info.el
+++ b/lisp/casual-info.el
@@ -48,7 +48,8 @@
   "CC Info Transient menu."
 
   [["Overview"
-    ("d" "Directory" Info-directory :transient nil)
+    ("d" "Directory" Info-directory)
+    ("M" "Manual…" info-display-manual)
     ("t" "Top" Info-top-node)
     ("T" "ToC" Info-toc :transient nil)]
 
diff --git a/lisp/casual.el b/lisp/casual.el
index 40496288b0..11f705d99e 100644
--- a/lisp/casual.el
+++ b/lisp/casual.el
@@ -5,7 +5,7 @@
 ;; Author: Charles Choi <[email protected]>
 ;; URL: https://github.com/kickingvegas/casual
 ;; Keywords: tools, wp
-;; Version: 2.2.8
+;; Version: 2.2.9-rc.1
 ;; Package-Requires: ((emacs "29.1") (transient "0.6.0"))
 
 ;; This program is free software; you can redistribute it and/or modify
diff --git a/tests/test-casual-editkit-utils.el 
b/tests/test-casual-editkit-utils.el
index 4e3cead7ff..18b89adcfe 100644
--- a/tests/test-casual-editkit-utils.el
+++ b/tests/test-casual-editkit-utils.el
@@ -608,15 +608,18 @@
   (let ((tmpfile "casual-editkit-transform-text-tmenu.txt"))
     (casualt-editkit-setup tmpfile)
     (cl-letf ((casualt-mock #'capitalize-dwim)
+              (casualt-mock #'upcase-initials-region)
               (casualt-mock #'downcase-dwim)
               (casualt-mock #'upcase-dwim))
 
       (let ((test-vectors
              '((:binding "c" :command capitalize-dwim)
+               (:binding "t" :command upcase-initials-region)
                (:binding "l" :command downcase-dwim)
                (:binding "u" :command upcase-dwim)
                (:binding "RET" :command transient-quit-all))))
 
+        (casualt-mock-active-region)
         (casualt-suffix-testcase-runner test-vectors
                                         #'casual-editkit-transform-text-tmenu
                                         '(lambda () (random 5000)))))
@@ -662,6 +665,121 @@
                                         '(lambda () (random 5000)))))
     (casualt-editkit-breakdown tmpfile)))
 
+
+(ert-deftest test-casual-editkit-narrow-tmenu ()
+  ;; TODO: need to test for region.
+  (let ((tmpfile "casual-editkit-narrow-tmenu.el"))
+    (casualt-editkit-setup tmpfile)
+    (cl-letf ((casualt-mock #'narrow-to-defun))
+      (let ((test-vectors
+             '((:binding "d" :command narrow-to-defun))))
+
+        (emacs-lisp-mode)
+        (insert "(defun foo() (message \"hi.\"))")
+        (goto-char (point-min))
+        (save-buffer)
+
+        (casualt-suffix-testcase-runner test-vectors
+                                        #'casual-editkit-narrow-tmenu
+                                        '(lambda () (random 5000)))))
+
+    (casualt-editkit-breakdown tmpfile))
+
+  (let ((tmpfile "casual-editkit-narrow-tmenu.org"))
+    (casualt-editkit-setup tmpfile)
+    (cl-letf ((casualt-mock #'org-narrow-to-subtree)
+              (casualt-mock #'org-narrow-to-block)
+              (casualt-mock #'org-narrow-to-element))
+
+      (let ((test-vectors
+             '((:binding "s" :command org-narrow-to-subtree)
+               ;; (:binding "e" :command org-narrow-to-element)
+               )))
+
+        (org-mode)
+        (insert "* Header 1\n")
+
+        (casualt-suffix-testcase-runner test-vectors
+                                        #'casual-editkit-narrow-tmenu
+                                        '(lambda () (random 5000))))
+      (widen)
+      (let ((test-vectors
+             '((:binding "b" :command org-narrow-to-block)
+               ;; (:binding "e" :command org-narrow-to-element)
+               )))
+
+        (insert "#+begin_src elisp\n")
+        (insert "hi there\n")
+        (insert "#+end_src\n")
+        (previous-line 2)
+
+        (casualt-suffix-testcase-runner test-vectors
+                                        #'casual-editkit-narrow-tmenu
+                                        '(lambda () (random 5000))))
+      (widen)
+      (let ((test-vectors
+             '((:binding "e" :command org-narrow-to-element))))
+
+        (insert "This is a bogus sentence.")
+        (beginning-of-line)
+
+        (casualt-suffix-testcase-runner test-vectors
+                                        #'casual-editkit-narrow-tmenu
+                                        '(lambda () (random 5000))))
+      (widen)
+      (save-buffer)
+      (casualt-editkit-breakdown tmpfile)))
+
+
+  ;; (let ((tmpfile "casual-editkit-narrow-tmenu.md"))
+  ;;   (casualt-editkit-setup tmpfile)
+  ;;   (cl-letf ((casualt-mock #'markdown-narrow-to-subtree)
+  ;;             (casualt-mock #'markdown-narrow-to-block)
+  ;;             (casualt-mock #'markdown-narrow-to-page))
+
+  ;;     (let ((test-vectors
+  ;;            '((:binding "s" :command markdown-narrow-to-subtree)
+
+  ;;              )))
+
+  ;;       (markdown-mode)
+  ;;       (insert "# Header 1\n")
+
+  ;;       (casualt-suffix-testcase-runner test-vectors
+  ;;                                       #'casual-editkit-narrow-tmenu
+  ;;                                       '(lambda () (random 5000))))
+
+  ;;     (widen)
+  ;;     (let ((test-vectors
+  ;;            '((:binding "b" :command markdown-narrow-to-block)
+  ;;              ;; (:binding "e" :command org-narrow-to-element)
+  ;;              )))
+
+  ;;       (insert "    #!python\n")
+  ;;       (insert "    def foo(a):\n")
+  ;;       (insert "        return a + 2\n")
+  ;;       (previous-line 2)
+
+  ;;       (casualt-suffix-testcase-runner test-vectors
+  ;;                                       #'casual-editkit-narrow-tmenu
+  ;;                                       '(lambda () (random 5000))))
+
+  ;;     (widen)
+
+  ;;     (let ((test-vectors
+  ;;            '((:binding "p" :command markdown-narrow-to-page))))
+
+  ;;       (insert "This is a bogus sentence.")
+  ;;       (beginning-of-line)
+
+  ;;       (casualt-suffix-testcase-runner test-vectors
+  ;;                                       #'casual-editkit-narrow-tmenu
+  ;;                                       '(lambda () (random 5000))))
+  ;;     (widen)
+  ;;     (save-buffer)
+  ;;     (casualt-editkit-breakdown tmpfile)))
+  )
+
 ;; -------
 (provide 'test-casual-editkit-utils)
 ;;; test-casual-editkit-utils.el ends here
diff --git a/tests/test-casual-editkit.el b/tests/test-casual-editkit.el
index fe410d8d22..1dab805df3 100644
--- a/tests/test-casual-editkit.el
+++ b/tests/test-casual-editkit.el
@@ -40,6 +40,7 @@
               (casualt-mock #'recentf-open-files)
               (casualt-mock #'revert-buffer)
               (casualt-mock #'save-buffer)
+              (casualt-mock #'widen)
 
               (casualt-mock #'insert-char)
               (casualt-mock #'fill-paragraph)
@@ -71,6 +72,9 @@
                (:binding "p" :command fill-paragraph)
                (:binding "l" :command join-line)
                (:binding "C-o" :command open-line)
+               (:binding "N" :command casual-editkit-narrow-tmenu)
+               ;; (:binding "W" :command widen)
+
                (:binding "E" :command casual-editkit-emoji-symbols-tmenu)
 
                (:binding "m" :command mark-sexp)
@@ -100,13 +104,23 @@
                (:binding "," :command casual-editkit-settings-tmenu)
                (:binding "x" :command save-buffers-kill-emacs))))
 
-
         (insert "hello")
         (casualt-suffix-testcase-runner test-vectors
                                         #'casual-editkit-main-tmenu
                                         '(lambda () (random 5000)))
         (save-buffer)))
 
+    (cl-letf (((symbol-function #'buffer-narrowed-p) (lambda () t))
+              (casualt-mock #'widen))
+
+      (let ((test-vectors
+             '((:binding "W" :command widen))))
+
+        (insert "hello")
+        (casualt-suffix-testcase-runner test-vectors
+                                        #'casual-editkit-main-tmenu
+                                        '(lambda () (random 5000)))
+        (save-buffer)))
     (casualt-editkit-breakdown tmpfile)))
 
 (provide 'test-casual-editkit)
diff --git a/tests/test-casual-info.el b/tests/test-casual-info.el
index 47d5e32262..9a557d0082 100644
--- a/tests/test-casual-info.el
+++ b/tests/test-casual-info.el
@@ -33,6 +33,7 @@
     (casualt-info-setup)
     (cl-letf (
               (casualt-mock #'Info-directory)
+              (casualt-mock #'info-display-manual)
               (casualt-mock #'Info-top-node)
               (casualt-mock #'Info-toc)
               (casualt-mock #'Info-menu)
@@ -69,6 +70,7 @@
       (let ((test-vectors
              '(;; Overview
                (:binding "d" :command Info-directory)
+               (:binding "M" :command info-display-manual)
                (:binding "t" :command Info-top-node)
                (:binding "T" :command Info-toc)
 

Reply via email to