branch: elpa/casual
commit 92bd1a2f0f4c091938290f8bb8e9b45d76439855
Merge: 5ffd4d9928 a86074d50c
Author: Charles Choi <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #182 from
kickingvegas/merge-development-to-main-20250312_160657
Merge development to main 20250312_160657
---
README.org | 9 +-
docs/Makefile | 15 +
docs/casual.info | 1347 ++++++++++++++++++++
docs/casual.org | 899 +++++++++++++
.../casual-editkit-emoji-symbols-screenshot.png | Bin 198011 -> 143252
bytes
.../casual-make-automatic-variables-screenshot.png | Bin 0 -> 202163 bytes
docs/images/casual-make-mode-select-screenshot.png | Bin 0 -> 95538 bytes
docs/images/casual-make-screenshot.png | Bin 0 -> 257598 bytes
docs/make-mode.org | 76 ++
lisp/Makefile | 6 +-
lisp/Makefile-make-mode.make | 30 +
lisp/casual-editkit-utils.el | 2 +-
lisp/casual-editkit.el | 2 +-
lisp/casual-make-settings.el | 75 ++
lisp/casual-make-utils.el | 239 ++++
lisp/casual-make.el | 85 ++
lisp/casual.el | 6 +-
tests/Makefile | 5 +
tests/casual-make-test-utils.el | 70 +
tests/test-casual-editkit-utils.el | 8 +-
tests/test-casual-editkit.el | 4 +-
tests/test-casual-make-settings.el | 52 +
tests/test-casual-make-utils.el | 90 ++
tests/test-casual-make.el | 75 ++
24 files changed, 3084 insertions(+), 11 deletions(-)
diff --git a/README.org b/README.org
index 5d4117df6e..5ff910a845 100644
--- a/README.org
+++ b/README.org
@@ -41,6 +41,7 @@ Editorially, all design decisions for Casual are ultimately
the opinion of Charl
- [[#image-elisp-library-casual-image][Image (Elisp library:
~casual-image~)]]
- [[#info-elisp-library-casual-info][Info (Elisp library: ~casual-info~)]]
- [[#i-search-elisp-library-casual-isearch][I-Search (Elisp library:
~casual-isearch~)]]
+ - [[#make-elisp-library-casual-make][Make (Elisp library: ~casual-make~)]]
- [[#re-builder-elisp-library-casual-re-builder][Re-Builder (Elisp library:
~casual-re-builder~)]]
- [[#requirements][Requirements]]
- [[#install][Install]]
@@ -110,7 +111,12 @@ An interface for the Info documentation system.
An interface for the many commands supported by I-Search.
[[file:docs/isearch.org][file:docs/images/casual-isearch-tmenu.png]]
-
+
+** [[file:docs/make-mode.org][Make]] (Elisp library: ~casual-make~)
+An interface to ~make-mode~, a mode tailored for editing a Makefile.
+
+[[file:docs/make-mode.org][file:docs/images/casual-make-screenshot.png]]
+
** [[file:docs/re-builder.org][Re-Builder]] (Elisp library:
~casual-re-builder~)
An interface for the Emacs regular expression tool.
@@ -141,6 +147,7 @@ Configuration of a particular Casual user interface is
performed per mode. Go to
- [[file:docs/image.org::*Install][Image]]
- [[file:docs/info.org::*Install][Info]]
- [[file:docs/isearch.org::*Install][I-Search]]
+- [[file:docs/make-mode.org::*Install][Make]]
- [[file:docs/re-builder.org::*Install][Re-Builder]]
** Upgrading to Casual 2.x
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000000..9a8fdb44cf
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,15 @@
+##
+# Copyright 2024 Charles Y. Choi
+#
+
+TIMESTAMP := $(shell /bin/date "+%Y%m%d_%H%M%S")
+PKG_NAME=casual
+
+
+$(PKG_NAME).info: $(PKG_NAME).texi
+ texi2any $<
+
+run: $(PKG_NAME).info
+
+clean:
+ - rm $(PKG_NAME).texi
diff --git a/docs/casual.info b/docs/casual.info
new file mode 100644
index 0000000000..96416eb874
--- /dev/null
+++ b/docs/casual.info
@@ -0,0 +1,1347 @@
+This is casual.info, produced by makeinfo version 7.2 from casual.texi.
+
+INFO-DIR-SECTION Emacs misc features
+START-INFO-DIR-ENTRY
+* Casual: (casual). Transient user interfaces for different Emacs modes.
+END-INFO-DIR-ENTRY
+
+
+File: casual.info, Node: Top, Next: Motivations, Up: (dir)
+
+Casual User Guide
+*****************
+
+Version: 2.4.0
+
+Casual is a project to re-imagine the primary user interface for Emacs
+using keyboard-driven menus.
+
+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. While menus are commonly associated with mouse-driven
+UI, the inclusion of Transient (https://github.com/magit/transient) in
+Emacs core allows for building menus that are keyboard-driven instead.
+This appeals to users that prefer keyboard-driven workflows.
+
+Casual organizes itself primarily around the different built-in modes
+Emacs provides. For each mode Casual supports, there is a bespoke
+designed library of Transient menus for that mode's command set.
+
+Casual has no aims to be a mutually exclusive user interface. All
+existing user interfaces to commands (keybinding, mini-buffer prompt,
+mouse menus) are still available to the user.
+
+To learn more about the motivations and design considerations for Casual
+as well as seeing it at work, please watch the presentation
+“Re-imagining the Emacs User Experience with Casual Suite”
+(https://emacsconf.org/2024/talks/casual/) from EmacsConf 2024.
+
+* Menu:
+
+* Motivations::
+* Requirements::
+* Transient Conventions::
+* Casual Modes::
+* UX Conventions::
+* Customization::
+* Feedback & Discussion::
+* Sponsorship::
+* About::
+* Acknowledgments::
+* Index::
+* Variable Index::
+
+-- The Detailed Node Listing --
+
+Casual Modes
+
+* Agenda::
+* Bookmarks::
+* Calc::
+* Calendar::
+* Dired::
+* EditKit::
+* IBuffer::
+* Image::
+* Info::
+* I-Search::
+* Make::
+* RE-Builder::
+
+
+File: casual.info, Node: Motivations, Next: Requirements, Prev: Top, Up:
Top
+
+1 Motivations
+*************
+
+Goals
+=====
+
+ • To provide a keyboard-driven menu UI toolkit for common Emacs
+ commands.
+
+ • To allow for casual discovery and use of infrequently used Emacs
+ commands.
+
+ • To be a frequently used interface to the modes Casual does support.
+
+Non-Goals
+=========
+
+ • Full coverage of all Emacs commands. Casual is not intended to be
+ a power user tool nor is it intended to be a replacement for
+ mouse-driven menus. Casual has no intent to exhaustively cover all
+ modes available in Emacs with keyboard-driven menus.
+
+ • Strict adherence to Emacs command naming. While Casual is *mostly*
+ in alignment with Emacs command naming, there are cases where it
+ will make an opinionated change if the name is deemed too vague or
+ idiomatic.
+
+ • No intention is made by Casual to help on-board users to the
+ existing default bindings of a mode, nor to cater to users who
+ already know them. That said, many existing default Emacs bindings
+ are replicated in Casual. Such correspondence should be considered
+ incidental.
+
+ • UX Stability (for now). Given that Casual is early in its
+ life-cycle, expect changes to its user experience in terms of menu
+ hierarchy and keybinding choices in future releases.
+
+Editorially, all design decisions for Casual are ultimately the opinion
+of Charles Y. Choi.
+
+
+File: casual.info, Node: Requirements, Next: Transient Conventions, Prev:
Motivations, Up: Top
+
+2 Requirements
+**************
+
+Casual requires Emacs 29.1+.
+
+Certain menus require more:
+
+ • Casual Dired: GNU Coreutils
+ • Casual Image: ImageMagick 6+
+
+
+File: casual.info, Node: Transient Conventions, Next: Casual Modes, Prev:
Requirements, Up: Top
+
+3 Transient Conventions
+***********************
+
+Casual is built using Transient menus and as such adopts its default
+behavior.
+
+Each menu item has a _key_ and a _label_. The _key_ is what is typed by
+the user to select the menu item. A key can be prefixed with a meta
+‘M-’ or control ‘C-’ key.
+
+Transient supports nested menus. Exiting a menu can be done in two
+ways:
+
+ • ‘C-g’ (‘transient-quit-one’) will exit the current sub-menu and
+ return you back to its parent menu.
+
+ • ‘C-q’ (‘transient-quit-all’) will exit you completely from a
+ Transient menu stack.
+
+If a mouse is available, a menu item can be selected by moving the mouse
+cursor over its label and pressing down button 1.
+
+Pressing the ‘?’ key or ‘C-h’ will toggle help for all the menu items.
+Press the key of interest to get help for it.
+
+When a Transient menu is raised, a prefix argument (‘C-u’) and an
+optional argument can be entered before selecting a menu item.
+
+For Transient menus that offer setting different values, the following
+bindings will allow you save them:
+
+ • ‘C-x s’ (‘transient-set’)
+
+ Saves the value of the active transient for this Emacs session.
+
+ • ‘C-x C-s’ (‘transient-save’)
+
+ Saves the value of the active transient persistently across Emacs
+ sessions.
+
+ • ‘C-x C-k’ (‘transient-reset’)
+
+ Clears the set and saved values of the active transient.
+
+References
+==========
+
+ • *note Aborting and Resuming Transients: (transient)Aborting and
+ Resuming Transients.
+ • *note Saving Values: (transient)Saving Values.
+
+
+File: casual.info, Node: Casual Modes, Next: UX Conventions, Prev:
Transient Conventions, Up: Top
+
+4 Casual Modes
+**************
+
+Casual employs the convention of using the same keybinding to invoke a
+mode-specific main menu. This keybinding is re-used for each
+mode-specific keymap. The document recommends the default keybinding
+‘C-o’ for this purpose. Users who prefer a different binding are always
+free to use another.
+
+Casual is organized into different libraries typically using the naming
+convention of ‘casual-<mode name>’. Each library has within it a "main
+menu" which serves as the top level interface to access functions
+related to that mode. All main menus are auto-loaded, which means that
+it is not necessary to include a ‘require’ call to load that library.
+
+The following modes are supported by Casual:
+
+* Menu:
+
+* Agenda::
+* Bookmarks::
+* Calc::
+* Calendar::
+* Dired::
+* EditKit::
+* IBuffer::
+* Image::
+* Info::
+* I-Search::
+* Make::
+* RE-Builder::
+
+
+File: casual.info, Node: Agenda, Next: Bookmarks, Up: Casual Modes
+
+4.1 Agenda
+==========
+
+Casual Agenda is a user interface for Org Agenda. Its top-level library
+is ‘casual-agenda’.
+
+Configuration
+=============
+
+The main menu for Casual Agenda is the Transient menu
+‘casual-agenda-tmenu’. Bind this menu in the keymap
+‘org-agenda-mode-map’ as follows in your initialization file.
+
+ (keymap-set org-agenda-mode-map "C-o" #'casual-agenda-tmenu)
+
+Use these bindings to configure Org Agenda to be consistent with
+bindings used by Casual Agenda. This is optional.
+
+ ; bindings to make jumping consistent between Org Agenda and Casual Agenda
+ (keymap-set org-agenda-mode-map "M-j" #'org-agenda-clock-goto) ; optional
+ (keymap-set org-agenda-mode-map "J" #'bookmark-jump) ; optional
+
+Usage
+=====
+
+Casual Agenda organizes its main menu into the following sections:
+
+ • *Agenda*
+
+ Modify the view duration (day, week, fortnight, month, year).
+
+ • *Filter*
+
+ Filter displayed headlines with different criteria.
+
+ • *Actions*
+
+ Perform an activity on a headline, create/capture a headline or
+ even generate a different agenda view.
+
+ • *Navigation*
+
+ Navigate to different agenda items by line, heading, or date. Move
+ the point to where you want it to be.
+
+ • *Utils*
+
+ Miscellaneous commands such as setting a time, showing the
+ calendar, and getting almanac information (sunrise/sunset, lunar
+ cycle).
+
+References
+==========
+
+ • *note Org Agenda: (org)Agenda Views.
+
+
+File: casual.info, Node: Bookmarks, Next: Calc, Prev: Agenda, Up: Casual
Modes
+
+4.2 Bookmarks
+=============
+
+Casual Bookmarks is a user interface for the Emacs Bookmarks list. Its
+top-level library is ‘casual-bookmarks’.
+
+Configuration
+=============
+
+The main menu for Casual Bookmarks is ‘casual-bookmarks-tmenu’. Bind
+this menu in the keymap ‘bookmark-bmenu-mode-map’ as follows in your
+initialization file.
+
+ (keymap-set bookmark-bmenu-mode-map "C-o" #'casual-bookmarks-tmenu)
+
+Use these keybindings to configure bookmark list to be consistent with
+keybindings used by Casual Bookmarks.
+
+ (keymap-set bookmark-bmenu-mode-map "J" #'bookmark-jump)
+
+Casual Bookmarks also includes the keymap ‘casual-bookmarks-main-menu’
+which inserts a _Bookmarks_ menu into the main menu bar.
+
+To enable this, add the following configuration to your initialization
+file.
+
+ (require 'casual-bookmarks)
+ (easy-menu-add-item global-map '(menu-bar)
+ casual-bookmarks-main-menu
+ "Tools")
+
+While not necessary, having the current bookmark highlighted is
+convenient. Enable ‘hl-line-mode’ for the bookmark list as shown below.
+
+ (require 'hl-line)
+ (add-hook 'bookmark-bmenu-mode-hook #'hl-line-mode)
+
+Finally, customize the variable ‘bookmark-save-flag’ to the value ‘1’ to
+ensure that your bookmark changes are always saved.
+
+The above guidance largely extends the work done in the blog post Using
+Bookmarks in Emacs like you do in Web Browsers
+(http://yummymelon.com/devnull/using-bookmarks-in-emacs-like-you-do-in-web-browsers.html).
+
+Usage
+=====
+
+Casual Bookmarks organizes its main menu into the following sections:
+
+ • *Operations*
+
+ Commands that can operate on a bookmark such as editing or opening
+ them.
+
+ • *Mark*
+
+ Commands that allow for bulk operation on multiple bookmarks.
+
+ • *Display*
+
+ Control how bookmarks are displayed and filtered.
+
+ • *Annotation*
+
+ Commands for annotating a bookmark.
+
+ • *Navigation*
+
+ Commands for navigating to a bookmark.
+
+ • *Column*
+
+ Commands to navigate and control the display of the table layout
+ for bookmarks.
+
+References
+==========
+
+ • *note Bookmarks: (emacs)Bookmarks.
+
+
+File: casual.info, Node: Calc, Next: Calendar, Prev: Bookmarks, Up: Casual
Modes
+
+4.3 Calc
+========
+
+Casual Calc is a user interface for Emacs Calc. Its top-level library
+is ‘casual-calc’.
+
+Configuration
+=============
+
+The main menu for Casual Calc is ‘casual-calc-tmenu’. Bind this menu in
+the keymaps ‘calc-mode-map’ and ‘calc-alg-map’ as follows in your
+initialization file.
+
+ (keymap-set calc-mode-map "C-o" #'casual-calc-tmenu)
+ (keymap-set calc-alg-map "C-o" #'casual-calc-tmenu)
+
+Usage
+=====
+
+Casual Calc organizes its main menu into the following sections:
+
+ • *Calc*
+
+ Commands for common calculator functions.
+
+ • *Constants*
+
+ Common math constants.
+
+ • *Operators*
+
+ Common math operators.
+
+ • *Stack*
+
+ Commands for stack operations.
+
+ • *Arithmetic*
+
+ Entry point for sub-menus of commands classified as arithmetic
+ operations.
+
+ • *Functions*
+
+ Entry point for sub-menus of commands organized into different
+ classes of functionality.
+
+ • *Settings*
+
+ Entry point for sub-menus of commands to configure Calc settings.
+
+To see the main menu in action do the following:
+
+ 1. Invoke ‘M-x calc’ to launch Calc.
+ 2. When the point is in the Calc window, invoke ‘C-o’ (or a binding of
+ your choosing) to launch the Casual Calc interface.
+
+For nearly all menus, algebraic entry via the ‘'’ binding is available,
+as well as basic calculator operations (addition, subtraction,
+multiplication, division) and stack operations (pop, enter).
+
+Calc Basics
+-----------
+
+It helps to know some basics about Calc.
+
+ • Calc is a stack-based calculator that supports both RPN and
+ algebraic style entry.
+ • By default it uses RPN entry, but this can be changed to
+ algebraic.
+ • Stack based operations are always RPN-style.
+ • Undo has the keybinding ‘U’, redo is ‘D’.
+ • The top of the stack is referred to as ‘1:’
+ • Calc vectors are punctuated with ‘[’ and ‘]’ (e.g. ‘[2 3]’) Matrix
+ values are represented as vectors within a vector. For example,
+ ‘[[1 0] [0 1]]’ is a square diagonal matrix.
+ • Calc vector indexes are 1-offset.
+ • Intervals
+ • Inclusive intervals are represented as [𝑛..𝑚], where 𝑛 < 𝑚.
+ • Exclusive intervals are represented as (𝑛..𝑚), where 𝑛 < 𝑚.
+ • Any combination of lower and upper bounds set to be inclusive
+ or exclusive is supported.
+ • Complex numbers are entered as (𝑟, 𝑖), where 𝑟 is the real part and
+ 𝑖 is the imaginary.
+ • Radix numbers are entered as 𝑏#𝑛 where 𝑏 is the base value and 𝑛 is
+ the number. For example entering ‘2#0101’ will put ‘5’ on the
+ stack.
+ • H:M:S values are default entered as ℎ@ 𝑚" 𝑠'.
+ • Org-mode active timestamps can be entered into Calc.
+ • The top of the stack (1:) can be edited by pressing the ‘`’ key.
+ • Entering a single quote ‘'’ will prompt you for an algebraic entry.
+
+References
+==========
+
+ • *note Calc: (calc)Top.
+
+
+File: casual.info, Node: Calendar, Next: Dired, Prev: Calc, Up: Casual
Modes
+
+4.4 Calendar
+============
+
+Casual Calendar is a user interface for Emacs Calendar/Diary. Its
+top-level library is ‘casual-calendar’. Access to numerous calendar and
+diary commands are made available, most notably support for
+non-Gregorian calendar systems.
+
+Configuration
+=============
+
+The main menu for Casual Calendar is ‘casual-calendar-tmenu’ that is
+wrapped by the command ‘casual-calendar’. Bind this command in the
+keymap ‘calendar-mode-map’ as follows in your initialization file.
+
+ (keymap-set calendar-mode-map "C-o" #'casual-calendar)
+
+Usage
+=====
+
+Casual Calendar organizes its main menu into the following sections:
+
+ • *Navigation*
+
+ Commands to move the point to a desired date, adjusting the view as
+ necessary.
+
+ • *Conversions*
+
+ Commands to convert a date across different calendar systems.
+
+ • *Holidays*
+
+ Holiday related commands.
+
+ • *Misc*
+
+ Commands related to the Diary and Org Agenda are placed here.
+
+ • *Almanac*
+
+ Almanac-related commands such the lunar phase, sunrise/sunset times
+ are found here.
+
+ • *Region*
+
+ Support for counting days defined in a region is offered here.
+
+References
+==========
+
+ • *note Calendar/Diary: (emacs)Calendar/Diary.
+
+
+File: casual.info, Node: Dired, Next: EditKit, Prev: Calendar, Up: Casual
Modes
+
+4.5 Dired
+=========
+
+Casual Dired provides a user interface for Dired, the Emacs file
+manager. Its top-level library is ‘casual-dired’.
+
+Requirements
+============
+
+Casual Dired requires that the ‘ls’ utility from GNU coreutils ≥ 8.32 be
+installed.
+
+The following links provide guidance for installing GNU coreutils on
+different platforms.
+
+macOS
+-----
+
+Note that the default packaged ‘ls’ on macOS is BSD-flavored which is
+not supported by Casual Dired. Users wishing to use Casual Dired on
+macOS are recommended to install GNU coreutils and configure their Emacs
+to point to its version of ‘ls’ accordingly.
+
+ • MacPorts (https://ports.macports.org/port/coreutils/)
+ • Homebrew (https://formulae.brew.sh/formula/coreutils#default)
+
+Windows
+-------
+
+For users running on Microsoft Windows, use this guidance
+(https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Dired-ls.html)
+to configure Emacs to use an external install of ‘ls’.
+
+ • Git for Windows (https://gitforwindows.org/) (includes ‘ls’ in Git
+ BASH)
+ • Cygwin (https://www.cygwin.com/)
+
+Configuration
+=============
+
+The main menu for Dired is ‘casual-dired-tmenu’. Bind this menu in the
+keymap ‘dired-mode-map’ as follows in your initialization file.
+
+ (keymap-set dired-mode-map "C-o" #'casual-dired-tmenu)
+
+In addition, it is convenient to have both the sort-by
+(‘casual-dired-sort-by-tmenu’) and search & replace
+(‘casual-dired-search-replace-tmenu’) menus bound. Listed below is an
+example of binding the sort-by and search & replace menus to ‘s’ and ‘/’
+respectively.
+
+ (keymap-set dired-mode-map "s" #'casual-dired-sort-by-tmenu) ; optional
+ (keymap-set dired-mode-map "/" #'casual-dired-search-replace-tmenu) ;
optional
+
+Usage
+=====
+
+Casual Dired organizes its main menu into the following sections:
+
+ • *File*
+
+ File-related commands are placed here. Most of the commands will
+ also operate on marked files (see *Mark* item below).
+
+ • *Directory*
+
+ Directory-related commands. Subdir view commands are also made
+ available in this section. To remove a subdir view, use the prefix
+ ‘C-u’ before pressing the binding ‘k’ to kill a subdir view.
+
+ • *Mark*
+
+ Marking operations are available here. Commands in the _Utils_
+ sub-menu can be used to operate on marked items. In addition, many
+ commands from the *Files* section can be operate on marked items.
+
+ The _Regexp_ sub-menu provides commands to mark via *note regular
+ expression: (elisp)Regular Expressions.
+
+ • *Navigation*
+
+ Navigation commands to move the point in Dired are offered here.
+
+ • *Quick*
+
+ Convenience commands for bookmarks and listing buffers are made
+ available in this section.
+
+ • *Search*
+
+ Commands to find a filename via I-Search or to recursively search
+ for pattern inside files contained in a directory tree (‘rgrep’)
+ are made available here.
+
+ • *New*
+
+ Create a new file or directory with the commands in this section.
+
+References
+==========
+
+ • *note Dired: (emacs)Dired.
+
+
+File: casual.info, Node: EditKit, Next: IBuffer, Prev: Dired, Up: Casual
Modes
+
+4.6 EditKit
+===========
+
+Casual EditKit provides a user interface for the numerous editing
+commands offered by Emacs. Its top-level library is ‘casual-editkit’.
+As text editing is a core feature of Emacs, the menus provided here are
+intended to be made available in a global fashion for buffers that are
+intended to be edited.
+
+Configuration
+=============
+
+The main menu for EditKit is ‘casual-editkit-main-tmenu’. Bind this
+menu in the global keymap to have general access to it whenever you are
+in a buffer whose mode does _not_ have Casual specific main menu as
+follows in your initialization file.
+
+ (keymap-global-set "C-o" #'casual-editkit-main-tmenu)
+
+Usage
+=====
+
+The main menu of Casual EditKit (‘casual-editkit-main-tmenu’) is
+organized into the following sections:
+
+ • *File*
+
+ Commands related to opening files or buffers are provided here.
+
+ • *Edit*
+
+ Text editing commands are provided here.
+
+ From this section, rectangle commands are made available via the
+ ‘(e) Edit → (R) Rectangle’ binding combination.
+
+ • *Sexp*
+
+ Text editing commands specific for a balanced expression (Sexp) are
+ provided here.
+
+ • *Tools*
+
+ Commands for invoking different tools are provided here.
+
+ • *Miscellaneous* (unlabeled)
+
+ Commands related to bookmarks, window management, project (Emacs
+ file organization), search & replace, and macros are found here.
+
+Casual EditKit has support for Register commands by providing a sub-menu
+for it in the navigation row at the bottom of the main menu.
+
+References
+==========
+
+ • *note Registers: (emacs)Registers.
+
+
+File: casual.info, Node: IBuffer, Next: Image, Prev: EditKit, Up: Casual
Modes
+
+4.7 IBuffer
+===========
+
+Casual IBuffer provides a user interface to Emacs IBuffer, a mode
+designed for managing buffers. Its top-level library is
+‘casual-ibuffer’.
+
+IBuffer is a powerful tool for managing Emacs workflows. As Emacs is
+often compared to an operating system, through that lens one could
+compare IBuffer to being a task manager interface, managing instantiated
+buffers as opposed to processes.
+
+Configuration
+=============
+
+The main menu for IBuffer is ‘casual-ibuffer-tmenu’. Bind this menu in
+the keymap ‘ibuffer-mode-map’ as follows in your initialization file.
+
+ (keymap-set ibuffer-mode-map "C-o" #'casual-ibuffer-tmenu)
+
+Like with Casual Dired, it is convenient to have the menus for filtering
+and sorting bound as well. Listed below shows an example of binding
+‘casual-ibuffer-filter-tmenu’ and ‘casual-ibuffer-sortby-tmenu’ to ‘F’
+and ‘s’ respectively.
+
+ (keymap-set ibuffer-mode-map "F" #'casual-ibuffer-filter-tmenu)
+ (keymap-set ibuffer-mode-map "s" #'casual-ibuffer-sortby-tmenu)
+
+Usage
+=====
+
+The main menu of Casual IBuffer (‘casual-ibuffer-tmenu’) is organized
+into the following sections:
+
+ • *Operations*
+
+ Commands to operate either on the buffer at point or on marked
+ buffers.
+
+ • *Mark*
+
+ Commands to support the marking of buffers.
+
+ • *Display*
+
+ Commands to control the display of buffers. Buffers can be sorted
+ by different criteria.
+
+ • *Navigation*
+
+ Commands to navigate the buffer list.
+
+ • *Filter*
+
+ Commands related to filtering/organizing buffers. Support for
+ defining _Filter Groups_ is provided here.
+
+ • *Find/Replace in Marked*
+
+ Commands to search & replace text in marked buffers are provided
+ here. Note that commands in this section that modify buffers do
+ _not_ save said buffers.
+
+ • *Quick*
+
+ Command to jump to a bookmark.
+
+References
+==========
+
+ • *note IBuffer: (emacs)Buffer Menus.
+
+
+File: casual.info, Node: Image, Next: Info, Prev: IBuffer, Up: Casual Modes
+
+4.8 Image
+=========
+
+Casual Image is a user interface for Image Mode. Its top level library
+is ‘casual-image’.
+
+Configuration
+=============
+
+The main menu for Casual Image is ‘casual-image-tmenu’. Bind this menu
+in the keymap ‘image-mode-map’ as follows in your initialization file.
+
+ (keymap-set image-mode-map "C-o" #'casual-image-tmenu)
+
+Usage
+=====
+
+The main menu for Casual Image (‘casual-image-tmenu’) is organized into
+the following sections:
+
+ • *View*
+
+ Commands to control the display of the image. None of these
+ commands will mutate the image file.
+
+ • *Edit*
+
+ Commands to edit the image file.
+
+ • *Scroll*
+
+ Commands to scroll an image view that is larger than its window
+ size.
+
+ • *Edge*
+
+ Commands to navigate to the edges of an image view that is larger
+ than its window size.
+
+ • *Traverse*
+
+ Commands to navigate to other image files in the same directory as
+ the current image.
+
+ • *Mark*
+
+ Commands to mark in Dired the current image.
+
+ • *Misc*
+
+ Miscellaneous commands.
+
+References
+==========
+
+ • *note Image Mode: (emacs)Image Mode.
+
+
+File: casual.info, Node: Info, Next: I-Search, Prev: Image, Up: Casual
Modes
+
+4.9 Info
+========
+
+Casual Info is a user interface for the Emacs Info Reader. Its top
+level library is ‘casual-info’.
+
+Configuration
+=============
+
+The main menu for Casual Info is ‘casual-info-tmenu’. Bind this menu in
+the keymap ‘Info-mode-map’ as follows in your initialization file.
+
+ (keymap-set Info-mode-map "C-o" #'casual-info-tmenu)
+
+Usage
+=====
+
+The main menu for Casual Info is organized into the following sections:
+
+ • *Overview*
+
+ Commands that navigate you to a starting point in the info
+ documentation.
+
+ • *Goto*
+
+ Commands that have you specify where to goto in the structure of an
+ Info document.
+
+ • *Search*
+
+ Commands for searching Info.
+
+ • *History*
+
+ Commands related to the history of pages (nodes) navigated to in
+ Info. Note that these commands should not be confused with
+ structural navigation.
+
+ • *Scroll*
+
+ Commands to scroll down or up the current Info page.
+
+ • *Navigation*
+
+ Command related to structurally navigating an Info document. Note
+ that these commands should not be confused with historical
+ navigation.
+
+ • *Quick*
+
+ Miscellaneous commands for working with an Info document. Included
+ are commands for bookmarks, copying the current node name, and
+ cloning the buffer.
+
+References
+==========
+
+ • *note Info: (info)Top.
+
+
+File: casual.info, Node: I-Search, Next: Make, Prev: Info, Up: Casual Modes
+
+4.10 I-Search
+=============
+
+Casual I-Search is a user interface for Incremental Search. Its top
+level library is ‘casual-isearch’.
+
+Configuration
+=============
+
+The main menu for Casual I-Search is ‘casual-isearch-tmenu’. Bind this
+menu in the keymap ‘isearch-mode-map’ as follows in your initialization
+file.
+
+ (keymap-set isearch-mode-map "C-o" #'casual-isearch-tmenu)
+
+Usage
+=====
+
+The main menu for Casual I-Search is organized into the following
+sections:
+
+ • *Edit Search String*
+
+ Commands to edit the search string. The type/extent of the string
+ (word, symbol, line, thing) can be specified here.
+
+ • *Replace*
+
+ Invoke ‘query-replace’ or ‘query-replace-regexp’ on matched
+ strings.
+
+ • *Toggle*
+
+ Commands to configure the type of search.
+
+ • *Misc*
+
+ Miscellaneous commands. From here the search string can be fed
+ into ‘occur’ or be highlighted.
+
+ • *Navigation*
+
+ Navigation commands for matched strings.
+
+References
+==========
+
+ • *note I-Search: (emacs)Incremental Search.
+
+
+File: casual.info, Node: Make, Next: RE-Builder, Prev: I-Search, Up:
Casual Modes
+
+4.11 Make
+=========
+
+Casual Make is a user interface to ‘make-mode’, a mode tailored for
+editing a Makefile.
+
+Configuration
+=============
+
+In your initialization file, bind the Transient ‘casual-make-tmenu’ to
+your key binding of preference. Two suggested bindings are ‘M-m’ or
+‘C-c m’.
+
+ (keymap-set makefile-mode-map "M-m" #'casual-make-tmenu)
+
+Usage
+=====
+
+It is recommended that some basic knowledge of the *make* command is
+known before using Casual Make.
+
+Basic Usage
+-----------
+
+When in a Makefile buffer, use ‘M-m’ (or your binding of choice) to
+raise the menu ‘casual-make-tmenu’. You will be presented with a menu
+with the following sections:
+
+ • Edit
+
+ Commands for editing the makefile. Note that the backslash and
+ comment commands require a region to be selected.
+
+ • Pickup as targets
+
+ Commands for synchronizing ‘make-mode’ with the target definitions
+ in the makefile. Use these commands if trying to insert a target
+ (via the ':' binding) does not include a target you have recently
+ entered.
+
+ • Misc
+
+ Miscellaneous commands related to working with a makefile.
+
+ • Navigate
+
+ Commands to support navigation within the makefile.
+
+Makefile Type Selection
+-----------------------
+
+As there are different variants of *make* and makefile formats, you can
+configure the mode for different specific makefile types. This can be
+done by selecting 'm' keybinding in ‘casual-make-tmenu’.
+
+Automatic Variables
+-------------------
+
+Casual Make provides a menu to enter GNU Make-style automatic variables.
+Note that each keybinding is identical to the automatic variable it
+represents to both reinforce its declaration and to avoid making another
+mapping. This menu is available from the 'i' keybinding in
+‘casual-make-tmenu’.
+
+Unless you edit makefiles frequently, it is very unlikely to be able to
+recall what an automatic variable declaration means. Casual Make
+provides the command ‘casual-make-identify-autovar-region’ to identify a
+selected automatic variable via the binding '.' in ‘casual-make-tmenu’.
+A short description of the automatic variable is shown in the
+mini-buffer.
+
+References
+==========
+
+ • *note Automatic Variables: (make)Automatic Variables.
+
+
+File: casual.info, Node: RE-Builder, Prev: Make, Up: Casual Modes
+
+4.12 RE-Builder
+===============
+
+Casual RE-Builder is a user interface for RE-Builder. Its top level
+library is ‘casual-re-builder’.
+
+Configuration
+=============
+
+The main menu for Casual RE-Builder is ‘casual-re-builder-tmenu’. Bind
+this menu in the keymaps ‘reb-mode-map’ and ‘reb-lisp-mode-map’ as
+follows in your initialization file.
+
+ (keymap-set reb-mode-map "C-o" #'casual-re-builder-tmenu)
+ (keymap-set reb-lisp-mode-map "C-o" #'casual-re-builder-tmenu)
+
+Usage
+=====
+
+Basic Usage
+-----------
+
+When the command ‘re-builder’ is invoked, a buffer named "✳︎RE-Builder✳︎"
+is created. Activate Casual RE-Builder with the binding ‘C-o’ (or one
+of your preference).
+
+At the top of the menu shows the title "RE-Builder" with the target
+buffer enclosed in parenthesis. The regexp pattern will be applied to
+the target buffer. The target buffer can be changed with the (b)
+*Target buffer* menu item.
+
+Emacs supports three different regexp syntax: 1) read, 2) string, 3) Rx.
+Use the (x) *Syntax* menu item to alter it. The current syntax is shown
+in parenthesis.
+
+If multiple sub-expressions are in the regexp pattern, then they can be
+observed via the (s) *Subexp mode* menu item.
+
+If the regexp pattern entered in the "✳︎RE-Builder✳︎" finds multiple
+matches, a match can be navigated to via the (p) *Previous* and (n)
+*Next* menu items.
+
+Exporting the Regexp Pattern
+----------------------------
+
+Once a desired regexp pattern is defined, there are two menu items that
+can be used to export (copy) it to the kill-ring for further use.
+
+ • (w) *Interactive* will copy the regexp to the kill-ring so that it
+ can be yanked in an interactive command that requires a regexp
+ (e.g. ‘query-replace-regexp’).
+ • This can only be used when the regexp syntax is set to
+ ‘string’.
+ • ❗️When yanking (typically ‘C-y’) a regexp into an interactive
+ prompt, you _must_ have the point/focus in the minibuffer
+ prompt (typically via mouse). Otherwise the desired content
+ can be altered with extra escaping.
+ • (c) *Code* will copy the regexp to the kill-ring so that it can be
+ yanked into a Elisp code that requires a regexp argument.
+ • (g) *Interactive grep* will copy the regexp so that it can be used
+ with command that take a GNU grep regex argument.
+ • Example commands that do this are ‘dired-do-find-regexp’ and
+ ‘dired-do-find-regexp-and-replace’.
+ • This command presumes that you have GNU grep installed and
+ configured for use by Emacs.
+ • ❗️At current this is an experimental feature. The regexp
+ exported from RE-Builder may not work. If so please report an
+ issue
+ (https://github.com/kickingvegas/casual-re-builder/issues)
+ describing the desired regexp and the target text.
+ • This can only be used when the regexp syntax is set to
+ ‘string’.
+
+Regexp Syntax Help
+------------------
+
+The menu item (i) will invoke the Info page for regexp syntax with
+respect to the current syntax type.
+
+Quitting RE-Builder
+-------------------
+
+Select (q) *Quit* to exit the RE-Builder tool.
+
+References
+==========
+
+ • *note Regular Expressions: (elisp)Regular Expressions.
+
+
+File: casual.info, Node: UX Conventions, Next: Customization, Prev: Casual
Modes, Up: Top
+
+5 UX Conventions
+****************
+
+The Casual menus share common user experience (UX) conventions to
+facilitate usability. This section details this.
+
+Common Menu Navigation
+======================
+
+Casual organizes a mode's command set into a menu hierarchy. As the
+user descends down different menu levels, the user is given the option
+to dismiss the current menu or to dismiss completely all menu levels
+descended. Transient provides a standard convention for menu dismissal
+via the ‘C-g’ (‘transient-quit-one’) and ‘C-q’ (‘transient-quit-all’)
+commands. By default Transient does not display these commands in the
+menu though, rather they make the assumption that the user already knows
+these bindings.
+
+In contrast, Casual makes these bindings explicitly known to user by
+displaying them at the bottom of the menu. Users who wish to have them
+hidden can set the customizable variable ‘casual-lib-hide-navigation’ to
+a non-nil value. This can be changed from a Casual mode-specific
+settings menu.
+
+Settings Menu
+=============
+
+Most all Casual main menus support invoking a mode-specific settings
+menu via the binding ','.
+
+Unicode Symbol Support
+======================
+
+The customizable variable named ‘casual-lib-use-unicode’ which when
+non-nil will inform Casual menus to use Unicode symbol labels whenever
+supported. This can be changed from Casual mode-specific settings menu.
+
+If ‘casual-lib-use-unicode’ is set to ‘t’, it is also recommended that
+the variable ‘transient-align-variable-pitch’ also be set to ‘t’.
+
+Common Key Bindings
+===================
+
+ • (J) ‘Jump to Bookmark…’
+
+ Casual places great emphasis on using Emacs Bookmarks to track
+ different places of note. The binding ‘J’ is used in many main
+ menus to support this.
+
+ • (,) ‘Settings›’
+
+ Many modes have settings specific to them. The binding ‘,’ is used
+ in many main menus to support the configuration of mode-specific
+ settings.
+
+ • (j) ‘Goto…’ (mode specific)
+
+ Many modes provide a list of items. The binding ‘j’ is used to map
+ to the command to move the point to an item that the user
+ explicitly specifies.
+
+ • (n), (p) ‘Next’, ‘Previous’
+
+ For modes that provide a list of items, navigation to a next or
+ previous item is bound to ‘n’ and ‘p’ respectively.
+
+ • ([), (]) ‘Next Section’, ‘Previous Section’
+
+ For modes that organize items into sections, navigation to a next
+ or previous section is bound to ‘[’ and ‘]’ respectively.
+
+
+File: casual.info, Node: Customization, Next: Feedback & Discussion, Prev:
UX Conventions, Up: Top
+
+6 Customization
+***************
+
+Users who wish to extend or alter existing Casual menus can do so via
+the mechanisms offered by the Transient package.
+
+References
+==========
+
+ • *note Modifying Existing Transients: (transient)Modifying Existing
+ Transients.
+
+
+File: casual.info, Node: Feedback & Discussion, Next: Sponsorship, Prev:
Customization, Up: Top
+
+7 Feedback & Discussion
+***********************
+
+Please report any feedback about Casual to the issue tracker on GitHub
+(https://github.com/kickingvegas/casual/issues).
+
+To participate in general discussion about using Casual, please join the
+discussion group (https://github.com/kickingvegas/casual/discussions).
+
+
+File: casual.info, Node: Sponsorship, Next: About, Prev: Feedback &
Discussion, Up: Top
+
+8 Sponsorship
+*************
+
+If you enjoy using Casual, consider making a modest financial
+contribution to help support its development and maintenance.
+
+<https://www.buymeacoffee.com/kickingvegas>
+
+
+File: casual.info, Node: About, Next: Acknowledgments, Prev: Sponsorship,
Up: Top
+
+9 About
+*******
+
+Casual (https://github.com/kickingvegas/casual) was conceived and
+crafted by Charles Choi in San Francisco, California.
+
+Thank you for using Casual.
+
+Always choose love.
+
+
+File: casual.info, Node: Acknowledgments, Next: Index, Prev: About, Up: Top
+
+10 Acknowledgments
+******************
+
+A heartfelt thanks to all the contributors to Transient
+(https://github.com/magit/transient), Magit (https://magit.vc), Org Mode
+(https://orgmode.org), and Emacs (https://www.gnu.org/software/emacs/).
+
+This package would not be possible without your efforts.
+
+
+File: casual.info, Node: Index, Next: Variable Index, Prev:
Acknowledgments, Up: Top
+
+11 Index
+********
+
+�[index�]
+* Menu:
+
+* About: About. (line 6)
+* Acknowledgments: Acknowledgments. (line 6)
+* Agenda (Org): Agenda. (line 6)
+* Agenda (Org) Configuration: Agenda. (line 12)
+* Agenda Usage: Agenda. (line 28)
+* Bookmarks: Bookmarks. (line 6)
+* Bookmarks Configuration: Bookmarks. (line 12)
+* Bookmarks Usage: Bookmarks. (line 50)
+* Calc: Calc. (line 6)
+* Calc Configuration: Calc. (line 12)
+* Calc Usage: Calc. (line 22)
+* Calendar: Calendar. (line 6)
+* Calendar Configuration: Calendar. (line 14)
+* Calendar Usage: Calendar. (line 23)
+* Casual Modes: Casual Modes. (line 6)
+* Customization: Customization. (line 6)
+* Dired: Dired. (line 6)
+* Dired Configuration: Dired. (line 43)
+* Dired Requirements: Dired. (line 12)
+* Dired Usage: Dired. (line 60)
+* Discussion: Feedback & Discussion.
+ (line 9)
+* EditKit: EditKit. (line 6)
+* EditKit Configuration: EditKit. (line 15)
+* EditKit Usage: EditKit. (line 25)
+* Feedback: Feedback & Discussion.
+ (line 6)
+* I-Search: I-Search. (line 6)
+* I-Search Configuration: I-Search. (line 12)
+* I-Search Usage: I-Search. (line 21)
+* IBuffer: IBuffer. (line 6)
+* IBuffer Configuration: IBuffer. (line 18)
+* IBuffer Usage: IBuffer. (line 34)
+* Image: Image. (line 6)
+* Image Configuration: Image. (line 12)
+* Image Usage: Image. (line 20)
+* Info: Info. (line 6)
+* Info Configuration: Info. (line 12)
+* Info Usage: Info. (line 20)
+* ISearch: I-Search. (line 6)
+* Make: Make. (line 6)
+* Make Configuration: Make. (line 12)
+* Make Usage: Make. (line 21)
+* Motivations: Motivations. (line 5)
+* RE-Builder: RE-Builder. (line 6)
+* RE-Builder Configuration: RE-Builder. (line 12)
+* RE-Builder Usage: RE-Builder. (line 21)
+* Requirements: Requirements. (line 6)
+* Sponsorship: Sponsorship. (line 6)
+* Transient Conventions: Transient Conventions.
+ (line 6)
+* UX Conventions: UX Conventions. (line 6)
+
+
+File: casual.info, Node: Variable Index, Prev: Index, Up: Top
+
+12 Variable Index
+*****************
+
+�[index�]
+* Menu:
+
+* casual-lib-hide-navigation: UX Conventions. (line 21)
+* casual-lib-use-unicode: UX Conventions. (line 36)
+
+
+Tag Table:
+Node: Top228
+Node: Motivations1923
+Node: Requirements3416
+Node: Transient Conventions3680
+Node: Casual Modes5408
+Node: Agenda6400
+Node: Bookmarks7957
+Node: Calc10232
+Node: Calendar13373
+Node: Dired14721
+Node: EditKit17946
+Node: IBuffer19670
+Node: Image21735
+Node: Info22976
+Node: I-Search24442
+Node: Make25603
+Node: RE-Builder27975
+Node: UX Conventions31382
+Node: Customization34083
+Node: Feedback & Discussion34457
+Node: Sponsorship34875
+Node: About35169
+Node: Acknowledgments35446
+Node: Index35828
+Node: Variable Index39730
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+Info-documentlanguage: en
+End:
diff --git a/docs/casual.org b/docs/casual.org
new file mode 100644
index 0000000000..ed0d06815e
--- /dev/null
+++ b/docs/casual.org
@@ -0,0 +1,899 @@
+#+TITLE: Casual User Guide
+#+SUBTITLE: for version {{{version}}}
+#+AUTHOR: Charles Y. Choi
+#+EMAIL: [email protected]
+
+#+OPTIONS: ':t toc:t author:t email:t compact-itemx:t
+#+LANGUAGE: en
+
+#+MACRO: version 2.4.0
+
+#+TEXINFO_FILENAME: casual.info
+#+TEXINFO_HEADER: @syncodeindex pg cp
+#+TEXINFO_HEADER: @paragraphindent none
+
+#+TEXINFO_DIR_CATEGORY: Emacs misc features
+#+TEXINFO_DIR_TITLE: Casual: (casual)
+#+TEXINFO_DIR_NAME: Casual
+#+TEXINFO_DIR_DESC: Transient user interfaces for different Emacs modes.
+#+TEXINFO_PRINTED_TITLE: Casual User Guide
+
+Version: {{{version}}}
+
+Casual is a project to re-imagine the primary user interface for Emacs using
keyboard-driven menus.
+
+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. While menus are commonly associated with mouse-driven UI, the
inclusion of [[https://github.com/magit/transient][Transient]] in Emacs core
allows for building menus that are keyboard-driven instead. This appeals to
users that prefer keyboard-driven workflows.
+
+Casual organizes itself primarily around the different built-in modes Emacs
provides. For each mode Casual supports, there is a bespoke designed library of
Transient menus for that mode's command set.
+
+Casual has no aims to be a mutually exclusive user interface. All existing
user interfaces to commands (keybinding, mini-buffer prompt, mouse menus) are
still available to the user.
+
+To learn more about the motivations and design considerations for Casual as
well as seeing it at work, please watch the presentation
[[https://emacsconf.org/2024/talks/casual/][“Re-imagining the Emacs User
Experience with Casual Suite”]] from EmacsConf 2024.
+
+* Motivations
+#+CINDEX: Motivations
+
+#+TEXINFO: @unnumberedsec Goals
+
+- To provide a keyboard-driven menu UI toolkit for common Emacs commands.
+
+- To allow for casual discovery and use of infrequently used Emacs commands.
+
+- To be a frequently used interface to the modes Casual does support.
+
+#+TEXINFO: @unnumberedsec Non-Goals
+
+- Full coverage of all Emacs commands. Casual is not intended to be a power
user tool nor is it intended to be a replacement for mouse-driven menus. Casual
has no intent to exhaustively cover all modes available in Emacs with
keyboard-driven menus.
+
+- Strict adherence to Emacs command naming. While Casual is *mostly* in
alignment with Emacs command naming, there are cases where it will make an
opinionated change if the name is deemed too vague or idiomatic.
+
+- No intention is made by Casual to help on-board users to the existing
default bindings of a mode, nor to cater to users who already know them. That
said, many existing default Emacs bindings are replicated in Casual. Such
correspondence should be considered incidental.
+
+- UX Stability (for now). Given that Casual is early in its life-cycle, expect
changes to its user experience in terms of menu hierarchy and keybinding
choices in future releases.
+
+Editorially, all design decisions for Casual are ultimately the opinion of
Charles Y. Choi.
+
+* Requirements
+#+CINDEX: Requirements
+
+Casual requires Emacs 29.1+.
+
+Certain menus require more:
+
+- Casual Dired: GNU Coreutils
+- Casual Image: ImageMagick 6+
+
+* Transient Conventions
+#+CINDEX: Transient Conventions
+
+Casual is built using Transient menus and as such adopts its default behavior.
+
+Each menu item has a /key/ and a /label/. The /key/ is what is typed by the
user to select the menu item. A key can be prefixed with a meta ~M-~ or control
~C-~ key.
+
+Transient supports nested menus. Exiting a menu can be done in two ways:
+
+- ~C-g~ (~transient-quit-one~) will exit the current sub-menu and return you
back to its parent menu.
+
+- ~C-q~ (~transient-quit-all~) will exit you completely from a Transient menu
stack.
+
+If a mouse is available, a menu item can be selected by moving the mouse
cursor over its label and pressing down button 1.
+
+Pressing the ~?~ key or ~C-h~ will toggle help for all the menu items. Press
the key of interest to get help for it.
+
+When a Transient menu is raised, a prefix argument (~C-u~) and an optional
argument can be entered before selecting a menu item.
+
+For Transient menus that offer setting different values, the following
bindings will allow you save them:
+
+- ~C-x s~ (~transient-set~)
+
+ Saves the value of the active transient for this Emacs session.
+
+- ~C-x C-s~ (~transient-save~)
+
+ Saves the value of the active transient persistently across Emacs sessions.
+
+- ~C-x C-k~ (~transient-reset~)
+
+ Clears the set and saved values of the active transient.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:transient#Aborting and Resuming Transients][Aborting and Resuming
Transients]]
+- [[info:transient#Saving Values][Saving Values]]
+
+* Casual Modes
+#+CINDEX: Casual Modes
+
+Casual employs the convention of using the same keybinding to invoke a
mode-specific main menu. This keybinding is re-used for each mode-specific
keymap. The document recommends the default keybinding ~C-o~ for this purpose.
Users who prefer a different binding are always free to use another.
+
+Casual is organized into different libraries typically using the naming
convention of ~casual-<mode name>~. Each library has within it a "main menu"
which serves as the top level interface to access functions related to that
mode. All main menus are auto-loaded, which means that it is not necessary to
include a ~require~ call to load that library.
+
+The following modes are supported by Casual:
+
+** Agenda
+#+CINDEX: Agenda (Org)
+Casual Agenda is a user interface for Org Agenda. Its top-level library is
~casual-agenda~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Agenda (Org) Configuration
+
+The main menu for Casual Agenda is the Transient menu ~casual-agenda-tmenu~.
Bind this menu in the keymap ~org-agenda-mode-map~ as follows in your
initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set org-agenda-mode-map "C-o" #'casual-agenda-tmenu)
+#+end_src
+
+Use these bindings to configure Org Agenda to be consistent with bindings used
by Casual Agenda. This is optional.
+
+#+begin_src elisp :lexical no
+ ; bindings to make jumping consistent between Org Agenda and Casual Agenda
+ (keymap-set org-agenda-mode-map "M-j" #'org-agenda-clock-goto) ; optional
+ (keymap-set org-agenda-mode-map "J" #'bookmark-jump) ; optional
+#+end_src
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Agenda Usage
+
+Casual Agenda organizes its main menu into the following sections:
+
+- *Agenda*
+
+ Modify the view duration (day, week, fortnight, month, year).
+
+- *Filter*
+
+ Filter displayed headlines with different criteria.
+
+- *Actions*
+
+ Perform an activity on a headline, create/capture a headline or even
generate a different agenda view.
+
+- *Navigation*
+
+ Navigate to different agenda items by line, heading, or date. Move the point
to where you want it to be.
+
+- *Utils*
+
+ Miscellaneous commands such as setting a time, showing the calendar, and
getting almanac information (sunrise/sunset, lunar cycle).
+
+
+#+TEXINFO: @unnumberedsec References
+- [[info:org#Agenda Views][Org Agenda]]
+
+** Bookmarks
+#+CINDEX: Bookmarks
+
+Casual Bookmarks is a user interface for the Emacs Bookmarks list. Its
top-level library is ~casual-bookmarks~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Bookmarks Configuration
+
+The main menu for Casual Bookmarks is ~casual-bookmarks-tmenu~. Bind this menu
in the keymap ~bookmark-bmenu-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set bookmark-bmenu-mode-map "C-o" #'casual-bookmarks-tmenu)
+#+end_src
+
+Use these keybindings to configure bookmark list to be consistent with
keybindings used by Casual Bookmarks.
+
+#+begin_src elisp :lexical no
+ (keymap-set bookmark-bmenu-mode-map "J" #'bookmark-jump)
+#+end_src
+
+Casual Bookmarks also includes the keymap ~casual-bookmarks-main-menu~ which
inserts a /Bookmarks/ menu into the main menu bar.
+
+To enable this, add the following configuration to your initialization file.
+
+#+begin_src elisp :lexical no
+ (require 'casual-bookmarks)
+ (easy-menu-add-item global-map '(menu-bar)
+ casual-bookmarks-main-menu
+ "Tools")
+#+end_src
+
+While not necessary, having the current bookmark highlighted is convenient.
Enable ~hl-line-mode~ for the bookmark list as shown below.
+
+#+begin_src elisp :lexical no
+ (require 'hl-line)
+ (add-hook 'bookmark-bmenu-mode-hook #'hl-line-mode)
+#+end_src
+
+Finally, customize the variable ~bookmark-save-flag~ to the value ~1~ to
ensure that your bookmark changes are always saved.
+
+The above guidance largely extends the work done in the blog post
[[http://yummymelon.com/devnull/using-bookmarks-in-emacs-like-you-do-in-web-browsers.html][Using
Bookmarks in Emacs like you do in Web Browsers]].
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Bookmarks Usage
+
+Casual Bookmarks organizes its main menu into the following sections:
+
+- *Operations*
+
+ Commands that can operate on a bookmark such as editing or opening them.
+
+- *Mark*
+
+ Commands that allow for bulk operation on multiple bookmarks.
+
+- *Display*
+
+ Control how bookmarks are displayed and filtered.
+
+- *Annotation*
+
+ Commands for annotating a bookmark.
+
+- *Navigation*
+
+ Commands for navigating to a bookmark.
+
+- *Column*
+
+ Commands to navigate and control the display of the table layout for
bookmarks.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Bookmarks][Bookmarks]]
+
+
+** Calc
+#+CINDEX: Calc
+
+Casual Calc is a user interface for Emacs Calc. Its top-level library is
~casual-calc~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Calc Configuration
+
+The main menu for Casual Calc is ~casual-calc-tmenu~. Bind this menu in the
keymaps ~calc-mode-map~ and ~calc-alg-map~ as follows in your initialization
file.
+
+#+begin_src elisp :lexical no
+ (keymap-set calc-mode-map "C-o" #'casual-calc-tmenu)
+ (keymap-set calc-alg-map "C-o" #'casual-calc-tmenu)
+#+end_src
+
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Calc Usage
+
+Casual Calc organizes its main menu into the following sections:
+
+- *Calc*
+
+ Commands for common calculator functions.
+
+- *Constants*
+
+ Common math constants.
+
+- *Operators*
+
+ Common math operators.
+
+- *Stack*
+
+ Commands for stack operations.
+
+- *Arithmetic*
+
+ Entry point for sub-menus of commands classified as arithmetic operations.
+
+- *Functions*
+
+ Entry point for sub-menus of commands organized into different classes of
functionality.
+
+- *Settings*
+
+ Entry point for sub-menus of commands to configure Calc settings.
+
+To see the main menu in action do the following:
+
+1. Invoke ~M-x calc~ to launch Calc.
+2. When the point is in the Calc window, invoke ~C-o~ (or a binding of your
choosing) to launch the Casual Calc interface.
+
+For nearly all menus, algebraic entry via the ~'~ binding is available, as
well as basic calculator operations (addition, subtraction, multiplication,
division) and stack operations (pop, enter).
+
+#+TEXINFO: @subsection Calc Basics
+It helps to know some basics about Calc.
+
+- Calc is a stack-based calculator that supports both RPN and algebraic style
entry.
+ - By default it uses RPN entry, but this can be changed to algebraic.
+- Stack based operations are always RPN-style.
+- Undo has the keybinding ~U~, redo is ~D~.
+- The top of the stack is referred to as ~1:~
+- Calc vectors are punctuated with ~[~ and ~]~ (e.g. ~[2 3]~) Matrix values
are represented as vectors within a vector. For example, ~[[1 0] [0 1]]~ is a
square diagonal matrix.
+- Calc vector indexes are 1-offset.
+- Intervals
+ - Inclusive intervals are represented as [𝑛..𝑚], where 𝑛 < 𝑚.
+ - Exclusive intervals are represented as (𝑛..𝑚), where 𝑛 < 𝑚.
+ - Any combination of lower and upper bounds set to be inclusive or exclusive
is supported.
+- Complex numbers are entered as (𝑟, 𝑖), where 𝑟 is the real part and 𝑖 is the
imaginary.
+- Radix numbers are entered as 𝑏#𝑛 where 𝑏 is the base value and 𝑛 is the
number. For example entering ~2#0101~ will put ~5~ on the stack.
+- H:M:S values are default entered as ℎ@ 𝑚" 𝑠'.
+- Org-mode active timestamps can be entered into Calc.
+- The top of the stack (1:) can be edited by pressing the ~`~ key.
+- Entering a single quote ~'~ will prompt you for an algebraic entry.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:calc][Calc]]
+
+** Calendar
+#+CINDEX: Calendar
+
+Casual Calendar is a user interface for Emacs Calendar/Diary. Its top-level
library is ~casual-calendar~. Access to numerous calendar and diary commands
are made available, most notably support for non-Gregorian calendar systems.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Calendar Configuration
+
+The main menu for Casual Calendar is ~casual-calendar-tmenu~ that is wrapped
by the command ~casual-calendar~. Bind this command in the keymap
~calendar-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set calendar-mode-map "C-o" #'casual-calendar)
+#+end_src
+
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Calendar Usage
+
+Casual Calendar organizes its main menu into the following sections:
+
+- *Navigation*
+
+ Commands to move the point to a desired date, adjusting the view as
necessary.
+
+- *Conversions*
+
+ Commands to convert a date across different calendar systems.
+
+- *Holidays*
+
+ Holiday related commands.
+
+- *Misc*
+
+ Commands related to the Diary and Org Agenda are placed here.
+
+- *Almanac*
+
+ Almanac-related commands such the lunar phase, sunrise/sunset times are
found here.
+
+
+- *Region*
+
+ Support for counting days defined in a region is offered here.
+
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Calendar/Diary][Calendar/Diary]]
+
+** Dired
+#+CINDEX: Dired
+
+Casual Dired provides a user interface for Dired, the Emacs file manager. Its
top-level library is ~casual-dired~.
+
+#+TEXINFO: @unnumberedsec Requirements
+#+CINDEX: Dired Requirements
+
+Casual Dired requires that the ~ls~ utility from GNU coreutils ≥ 8.32 be
installed.
+
+The following links provide guidance for installing GNU coreutils on different
platforms.
+
+#+TEXINFO: @unnumberedsubsec macOS
+Note that the default packaged ~ls~ on macOS is BSD-flavored which is not
supported by Casual Dired. Users wishing to use Casual Dired on macOS are
recommended to install GNU coreutils and configure their Emacs to point to its
version of ~ls~ accordingly.
+
+- [[https://ports.macports.org/port/coreutils/][MacPorts]]
+- [[https://formulae.brew.sh/formula/coreutils#default][Homebrew]]
+
+#+TEXINFO: @unnumberedsubsec Windows
+For users running on Microsoft Windows, use
[[https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Dired-ls.html][this
guidance]] to configure Emacs to use an external install of ~ls~.
+
+- [[https://gitforwindows.org/][Git for Windows]] (includes ~ls~ in Git BASH)
+- [[https://www.cygwin.com/][Cygwin]]
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Dired Configuration
+
+The main menu for Dired is ~casual-dired-tmenu~. Bind this menu in the keymap
~dired-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set dired-mode-map "C-o" #'casual-dired-tmenu)
+#+end_src
+
+In addition, it is convenient to have both the sort-by
(~casual-dired-sort-by-tmenu~) and search & replace
(~casual-dired-search-replace-tmenu~) menus bound. Listed below is an example
of binding the sort-by and search & replace menus to ~s~ and ~/~ respectively.
+
+#+begin_src elisp :lexical no
+ (keymap-set dired-mode-map "s" #'casual-dired-sort-by-tmenu) ; optional
+ (keymap-set dired-mode-map "/" #'casual-dired-search-replace-tmenu) ;
optional
+#+end_src
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Dired Usage
+
+Casual Dired organizes its main menu into the following sections:
+
+- *File*
+
+ File-related commands are placed here. Most of the commands will also
operate on marked files (see *Mark* item below).
+
+- *Directory*
+
+ Directory-related commands. Subdir view commands are also made available in
this section. To remove a subdir view, use the prefix ~C-u~ before pressing the
binding ~k~ to kill a subdir view.
+
+- *Mark*
+
+ Marking operations are available here. Commands in the /Utils/ sub-menu can
be used to operate on marked items. In addition, many commands from the *Files*
section can be operate on marked items.
+
+ The /Regexp/ sub-menu provides commands to mark via [[info:elisp#Regular
Expressions][regular expression]].
+
+- *Navigation*
+
+ Navigation commands to move the point in Dired are offered here.
+
+- *Quick*
+
+ Convenience commands for bookmarks and listing buffers are made available in
this section.
+
+- *Search*
+
+ Commands to find a filename via I-Search or to recursively search for
pattern inside files contained in a directory tree (~rgrep~) are made available
here.
+
+- *New*
+
+ Create a new file or directory with the commands in this section.
+
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Dired][Dired]]
+
+** EditKit
+#+CINDEX: EditKit
+
+Casual EditKit provides a user interface for the numerous editing commands
offered by Emacs. Its top-level library is ~casual-editkit~. As text editing is
a core feature of Emacs, the menus provided here are intended to be made
available in a global fashion for buffers that are intended to be edited.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: EditKit Configuration
+
+The main menu for EditKit is ~casual-editkit-main-tmenu~. Bind this menu in
the global keymap to have general access to it whenever you are in a buffer
whose mode does /not/ have Casual specific main menu as follows in your
initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-global-set "C-o" #'casual-editkit-main-tmenu)
+#+end_src
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: EditKit Usage
+
+The main menu of Casual EditKit (~casual-editkit-main-tmenu~) is organized
into the following sections:
+
+- *File*
+
+ Commands related to opening files or buffers are provided here.
+
+- *Edit*
+
+ Text editing commands are provided here.
+
+ From this section, rectangle commands are made available via the ~(e) Edit →
(R) Rectangle~ binding combination.
+
+- *Sexp*
+
+ Text editing commands specific for a balanced expression (Sexp) are provided
here.
+
+- *Tools*
+
+ Commands for invoking different tools are provided here.
+
+- *Miscellaneous* (unlabeled)
+
+ Commands related to bookmarks, window management, project (Emacs file
organization), search & replace, and macros are found here.
+
+Casual EditKit has support for Register commands by providing a sub-menu for
it in the navigation row at the bottom of the main menu.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Registers][Registers]]
+
+** IBuffer
+#+CINDEX: IBuffer
+
+Casual IBuffer provides a user interface to Emacs IBuffer, a mode designed for
managing buffers. Its top-level library is ~casual-ibuffer~.
+
+IBuffer is a powerful tool for managing Emacs workflows. As Emacs is often
compared to an operating system, through that lens one could compare IBuffer to
being a task manager interface, managing instantiated buffers as opposed to
processes.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: IBuffer Configuration
+
+The main menu for IBuffer is ~casual-ibuffer-tmenu~. Bind this menu in the
keymap ~ibuffer-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set ibuffer-mode-map "C-o" #'casual-ibuffer-tmenu)
+#+end_src
+
+Like with Casual Dired, it is convenient to have the menus for filtering and
sorting bound as well. Listed below shows an example of binding
~casual-ibuffer-filter-tmenu~ and ~casual-ibuffer-sortby-tmenu~ to ~F~ and ~s~
respectively.
+
+#+begin_src elisp :lexical no
+ (keymap-set ibuffer-mode-map "F" #'casual-ibuffer-filter-tmenu)
+ (keymap-set ibuffer-mode-map "s" #'casual-ibuffer-sortby-tmenu)
+#+end_src
+
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: IBuffer Usage
+
+The main menu of Casual IBuffer (~casual-ibuffer-tmenu~) is organized into the
following sections:
+
+- *Operations*
+
+ Commands to operate either on the buffer at point or on marked buffers.
+
+- *Mark*
+
+ Commands to support the marking of buffers.
+
+- *Display*
+
+ Commands to control the display of buffers. Buffers can be sorted by
different criteria.
+
+- *Navigation*
+
+ Commands to navigate the buffer list.
+
+- *Filter*
+
+ Commands related to filtering/organizing buffers. Support for defining
/Filter Groups/ is provided here.
+
+- *Find/Replace in Marked*
+
+ Commands to search & replace text in marked buffers are provided here. Note
that commands in this section that modify buffers do /not/ save said buffers.
+
+- *Quick*
+
+ Command to jump to a bookmark.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Buffer Menus][IBuffer]]
+
+
+** Image
+#+CINDEX: Image
+
+Casual Image is a user interface for Image Mode. Its top level library is
~casual-image~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Image Configuration
+
+The main menu for Casual Image is ~casual-image-tmenu~. Bind this menu in the
keymap ~image-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set image-mode-map "C-o" #'casual-image-tmenu)
+#+end_src
+
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Image Usage
+
+The main menu for Casual Image (~casual-image-tmenu~) is organized into the
following sections:
+
+- *View*
+
+ Commands to control the display of the image. None of these commands will
mutate the image file.
+
+- *Edit*
+
+ Commands to edit the image file.
+
+- *Scroll*
+
+ Commands to scroll an image view that is larger than its window size.
+
+- *Edge*
+
+ Commands to navigate to the edges of an image view that is larger than its
window size.
+
+- *Traverse*
+
+ Commands to navigate to other image files in the same directory as the
current image.
+
+- *Mark*
+
+ Commands to mark in Dired the current image.
+
+- *Misc*
+
+ Miscellaneous commands.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Image Mode][Image Mode]]
+
+
+** Info
+#+CINDEX: Info
+
+Casual Info is a user interface for the Emacs Info Reader. Its top level
library is ~casual-info~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Info Configuration
+
+The main menu for Casual Info is ~casual-info-tmenu~. Bind this menu in the
keymap ~Info-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set Info-mode-map "C-o" #'casual-info-tmenu)
+#+end_src
+
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Info Usage
+
+The main menu for Casual Info is organized into the following sections:
+
+- *Overview*
+
+ Commands that navigate you to a starting point in the info documentation.
+
+
+- *Goto*
+
+ Commands that have you specify where to goto in the structure of an Info
document.
+
+- *Search*
+
+ Commands for searching Info.
+
+- *History*
+
+ Commands related to the history of pages (nodes) navigated to in Info. Note
that these commands should not be confused with structural navigation.
+
+- *Scroll*
+
+ Commands to scroll down or up the current Info page.
+
+- *Navigation*
+
+ Command related to structurally navigating an Info document. Note that these
commands should not be confused with historical navigation.
+
+- *Quick*
+
+ Miscellaneous commands for working with an Info document. Included are
commands for bookmarks, copying the current node name, and cloning the buffer.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:info][Info]]
+
+** I-Search
+#+CINDEX: ISearch
+#+CINDEX: I-Search
+
+Casual I-Search is a user interface for Incremental Search. Its top level
library is ~casual-isearch~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: I-Search Configuration
+
+The main menu for Casual I-Search is ~casual-isearch-tmenu~. Bind this menu in
the keymap ~isearch-mode-map~ as follows in your initialization file.
+
+#+begin_src elisp :lexical yes
+ (keymap-set isearch-mode-map "C-o" #'casual-isearch-tmenu)
+#+end_src
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: I-Search Usage
+
+The main menu for Casual I-Search is organized into the following sections:
+
+- *Edit Search String*
+
+ Commands to edit the search string. The type/extent of the string (word,
symbol, line, thing) can be specified here.
+
+- *Replace*
+
+ Invoke ~query-replace~ or ~query-replace-regexp~ on matched strings.
+
+- *Toggle*
+
+ Commands to configure the type of search.
+
+- *Misc*
+
+ Miscellaneous commands. From here the search string can be fed into ~occur~
or be highlighted.
+
+- *Navigation*
+
+ Navigation commands for matched strings.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:emacs#Incremental Search][I-Search]]
+
+
+** Make
+#+CINDEX: Make
+
+Casual Make is a user interface to ~make-mode~, a mode tailored for editing a
Makefile.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: Make Configuration
+
+In your initialization file, bind the Transient ~casual-make-tmenu~ to your
key binding of preference. Two suggested bindings are ~M-m~ or ~C-c m~.
+
+#+begin_src elisp :lexical no
+ (keymap-set makefile-mode-map "M-m" #'casual-make-tmenu)
+#+end_src
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: Make Usage
+
+It is recommended that some basic knowledge of the *make* command is known
before using Casual Make.
+
+#+TEXINFO: @unnumberedsubsec Basic Usage
+
+When in a Makefile buffer, use ~M-m~ (or your binding of choice) to raise the
menu ~casual-make-tmenu~. You will be presented with a menu with the following
sections:
+
+- Edit
+
+ Commands for editing the makefile. Note that the backslash and comment
commands require a region to be selected.
+
+- Pickup as targets
+
+ Commands for synchronizing ~make-mode~ with the target definitions in the
makefile. Use these commands if trying to insert a target (via the ':' binding)
does not include a target you have recently entered.
+
+- Misc
+
+ Miscellaneous commands related to working with a makefile.
+
+- Navigate
+
+ Commands to support navigation within the makefile.
+
+
+#+TEXINFO: @unnumberedsubsec Makefile Type Selection
+
+As there are different variants of *make* and makefile formats, you can
configure the mode for different specific makefile types. This can be done by
selecting 'm' keybinding in ~casual-make-tmenu~.
+
+#+TEXINFO: @unnumberedsubsec Automatic Variables
+
+Casual Make provides a menu to enter GNU Make-style automatic variables. Note
that each keybinding is identical to the automatic variable it represents to
both reinforce its declaration and to avoid making another mapping. This menu
is available from the 'i' keybinding in ~casual-make-tmenu~.
+
+Unless you edit makefiles frequently, it is very unlikely to be able to recall
what an automatic variable declaration means. Casual Make provides the command
~casual-make-identify-autovar-region~ to identify a selected automatic variable
via the binding '.' in ~casual-make-tmenu~. A short description of the
automatic variable is shown in the mini-buffer.
+
+
+#+TEXINFO: @unnumberedsec References
+- [[info:make#Automatic Variables][Automatic Variables]]
+
+
+** RE-Builder
+#+CINDEX: RE-Builder
+
+Casual RE-Builder is a user interface for RE-Builder. Its top level library is
~casual-re-builder~.
+
+#+TEXINFO: @unnumberedsec Configuration
+#+CINDEX: RE-Builder Configuration
+
+The main menu for Casual RE-Builder is ~casual-re-builder-tmenu~. Bind this
menu in the keymaps ~reb-mode-map~ and ~reb-lisp-mode-map~ as follows in your
initialization file.
+
+#+begin_src elisp :lexical no
+ (keymap-set reb-mode-map "C-o" #'casual-re-builder-tmenu)
+ (keymap-set reb-lisp-mode-map "C-o" #'casual-re-builder-tmenu)
+#+end_src
+
+#+TEXINFO: @unnumberedsec Usage
+#+CINDEX: RE-Builder Usage
+
+#+TEXINFO: @unnumberedsubsec Basic Usage
+When the command ~re-builder~ is invoked, a buffer named "✳︎RE-Builder✳︎" is
created. Activate Casual RE-Builder with the binding ~C-o~ (or one of your
preference).
+
+At the top of the menu shows the title "RE-Builder" with the target buffer
enclosed in parenthesis. The regexp pattern will be applied to the target
buffer. The target buffer can be changed with the (b) *Target buffer* menu item.
+
+Emacs supports three different regexp syntax: 1) read, 2) string, 3) Rx. Use
the (x) *Syntax* menu item to alter it. The current syntax is shown in
parenthesis.
+
+If multiple sub-expressions are in the regexp pattern, then they can be
observed via the (s) *Subexp mode* menu item.
+
+If the regexp pattern entered in the "✳︎RE-Builder✳︎" finds multiple matches,
a match can be navigated to via the (p) *Previous* and (n) *Next* menu items.
+
+#+TEXINFO: @unnumberedsubsec Exporting the Regexp Pattern
+Once a desired regexp pattern is defined, there are two menu items that can be
used to export (copy) it to the kill-ring for further use.
+
+- (w) *Interactive* will copy the regexp to the kill-ring so that it can be
yanked in an interactive command that requires a regexp (e.g.
~query-replace-regexp~).
+ - This can only be used when the regexp syntax is set to ~string~.
+ - ❗️When yanking (typically ~C-y~) a regexp into an interactive prompt, you
/must/ have the point/focus in the minibuffer prompt (typically via mouse).
Otherwise the desired content can be altered with extra escaping.
+- (c) *Code* will copy the regexp to the kill-ring so that it can be yanked
into a Elisp code that requires a regexp argument.
+- (g) *Interactive grep* will copy the regexp so that it can be used with
command that take a GNU grep regex argument.
+ - Example commands that do this are ~dired-do-find-regexp~ and
~dired-do-find-regexp-and-replace~.
+ - This command presumes that you have GNU grep installed and configured for
use by Emacs.
+ - ❗️At current this is an experimental feature. The regexp exported from
RE-Builder may not work. If so please report an
[[https://github.com/kickingvegas/casual-re-builder/issues][issue]] describing
the desired regexp and the target text.
+ - This can only be used when the regexp syntax is set to ~string~.
+
+#+TEXINFO: @unnumberedsubsec Regexp Syntax Help
+The menu item (i) will invoke the Info page for regexp syntax with respect to
the current syntax type.
+
+#+TEXINFO: @unnumberedsubsec Quitting RE-Builder
+Select (q) *Quit* to exit the RE-Builder tool.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:elisp#Regular Expressions][Regular Expressions]]
+
+
+* UX Conventions
+#+CINDEX: UX Conventions
+
+The Casual menus share common user experience (UX) conventions to facilitate
usability. This section details this.
+
+#+TEXINFO: @unnumberedsec Common Menu Navigation
+
+Casual organizes a mode's command set into a menu hierarchy. As the user
descends down different menu levels, the user is given the option to dismiss
the current menu or to dismiss completely all menu levels descended. Transient
provides a standard convention for menu dismissal via the ~C-g~
(~transient-quit-one~) and ~C-q~ (~transient-quit-all~) commands. By default
Transient does not display these commands in the menu though, rather they make
the assumption that the user already knows [...]
+
+#+VINDEX: casual-lib-hide-navigation
+In contrast, Casual makes these bindings explicitly known to user by
displaying them at the bottom of the menu. Users who wish to have them hidden
can set the customizable variable ~casual-lib-hide-navigation~ to a non-nil
value. This can be changed from a Casual mode-specific settings menu.
+
+#+TEXINFO: @unnumberedsec Settings Menu
+
+Most all Casual main menus support invoking a mode-specific settings menu via
the binding ','.
+
+#+TEXINFO: @unnumberedsec Unicode Symbol Support
+#+VINDEX: casual-lib-use-unicode
+
+The customizable variable named ~casual-lib-use-unicode~ which when non-nil
will inform Casual menus to use Unicode symbol labels whenever supported. This
can be changed from Casual mode-specific settings menu.
+
+If ~casual-lib-use-unicode~ is set to ~t~, it is also recommended that the
variable ~transient-align-variable-pitch~ also be set to ~t~.
+
+#+TEXINFO: @unnumberedsec Common Key Bindings
+
+- (J) ~Jump to Bookmark…~
+
+ Casual places great emphasis on using Emacs Bookmarks to track different
places of note. The binding ~J~ is used in many main menus to support this.
+
+- (,) ~Settings›~
+
+ Many modes have settings specific to them. The binding ~,~ is used in many
main menus to support the configuration of mode-specific settings.
+
+- (j) ~Goto…~ (mode specific)
+
+ Many modes provide a list of items. The binding ~j~ is used to map to the
command to move the point to an item that the user explicitly specifies.
+
+- (n), (p) ~Next~, ~Previous~
+
+ For modes that provide a list of items, navigation to a next or previous
item is bound to ~n~ and ~p~ respectively.
+
+- ([), (]) ~Next Section~, ~Previous Section~
+
+ For modes that organize items into sections, navigation to a next or
previous section is bound to ~[~ and ~]~ respectively.
+
+* Customization
+#+CINDEX: Customization
+
+Users who wish to extend or alter existing Casual menus can do so via the
mechanisms offered by the Transient package.
+
+#+TEXINFO: @unnumberedsec References
+- [[info:transient#Modifying Existing Transients][Modifying Existing
Transients]]
+
+
+* Feedback & Discussion
+#+CINDEX: Feedback
+Please report any feedback about Casual to the
[[https://github.com/kickingvegas/casual/issues][issue tracker on GitHub]].
+
+#+CINDEX: Discussion
+To participate in general discussion about using Casual, please join the
[[https://github.com/kickingvegas/casual/discussions][discussion group]].
+
+* Sponsorship
+#+CINDEX: Sponsorship
+
+If you enjoy using Casual, consider making a modest financial contribution to
help support its development and maintenance.
+
+https://www.buymeacoffee.com/kickingvegas
+
+* About
+#+CINDEX: About
+
+[[https://github.com/kickingvegas/casual][Casual]] was conceived and crafted
by Charles Choi in San Francisco, California.
+
+Thank you for using Casual.
+
+Always choose love.
+
+* Acknowledgments
+#+CINDEX: Acknowledgments
+
+A heartfelt thanks to all the contributors to
[[https://github.com/magit/transient][Transient]], [[https://magit.vc][Magit]],
[[https://orgmode.org][Org Mode]], and
[[https://www.gnu.org/software/emacs/][Emacs]].
+
+This package would not be possible without your efforts.
+
+* Index
+:PROPERTIES:
+:INDEX: cp
+:END:
+
+* Variable Index
+:PROPERTIES:
+:INDEX: vr
+:END:
diff --git a/docs/images/casual-editkit-emoji-symbols-screenshot.png
b/docs/images/casual-editkit-emoji-symbols-screenshot.png
index 03aa45c516..44b22e588c 100644
Binary files a/docs/images/casual-editkit-emoji-symbols-screenshot.png and
b/docs/images/casual-editkit-emoji-symbols-screenshot.png differ
diff --git a/docs/images/casual-make-automatic-variables-screenshot.png
b/docs/images/casual-make-automatic-variables-screenshot.png
new file mode 100644
index 0000000000..41ba0256da
Binary files /dev/null and
b/docs/images/casual-make-automatic-variables-screenshot.png differ
diff --git a/docs/images/casual-make-mode-select-screenshot.png
b/docs/images/casual-make-mode-select-screenshot.png
new file mode 100644
index 0000000000..4f5c334741
Binary files /dev/null and b/docs/images/casual-make-mode-select-screenshot.png
differ
diff --git a/docs/images/casual-make-screenshot.png
b/docs/images/casual-make-screenshot.png
new file mode 100644
index 0000000000..eec1982eaa
Binary files /dev/null and b/docs/images/casual-make-screenshot.png differ
diff --git a/docs/make-mode.org b/docs/make-mode.org
new file mode 100644
index 0000000000..fb16580779
--- /dev/null
+++ b/docs/make-mode.org
@@ -0,0 +1,76 @@
+[[../README.org][❮ Back to Casual]]
+
+* Casual Make
+
+Casual Make is a user interface to ~make-mode~, a mode tailored for editing a
Makefile.
+
+[[file:images/casual-make-screenshot.png]]
+
+* Install
+
+In your initialization file, bind the Transient ~casual-make-tmenu~ to your
key binding of preference. Two suggested bindings are ~M-m~ or ~C-c m~.
+
+#+begin_src elisp :lexical no
+ (require 'casual-make) ; optional
+ (keymap-set makefile-mode-map "M-m" #'casual-make-tmenu)
+#+end_src
+
+* Usage
+
+It is recommended that some basic knowledge of the *make* command is known
before using Casual Make.
+
+** Basic Usage
+
+When in a Makefile buffer, use ~M-m~ (or your binding of choice) to raise the
menu ~casual-make-tmenu~. You will be presented with a menu with the following
sections:
+
+- Edit
+
+ Commands for editing the makefile. Note that the backslash and comment
commands require a region to be selected.
+
+- Pickup as targets
+
+ Commands for synchronizing ~make-mode~ with the target definitions in the
makefile. Use these commands if trying to insert a target (via the ':' binding)
does not include a target you have recently entered.
+
+- Misc
+
+ Miscellaneous commands related to working with a makefile.
+
+- Navigate
+
+ Commands to support navigation within the makefile.
+
+** Makefile Type Selection
+
+As there are different variants of *make* and makefile formats, you can
configure the mode for different specific makefile types. This can be done by
selecting 'm' keybinding in ~casual-make-tmenu~.
+
+[[file:images/casual-make-mode-select-screenshot.png]]
+
+
+** Automatic Variables
+
+Casual Make provides a menu to enter GNU Make-style
[[https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html][automatic
variables]]. Note that each keybinding is identical to the automatic variable
it represents to both reinforce its declaration and to avoid making another
mapping. This menu is available from the 'i' keybinding in ~casual-make-tmenu~.
+
+[[file:images/casual-make-automatic-variables-screenshot.png]]
+
+Unless you edit makefiles frequently, it is very unlikely to be able to recall
what an automatic variable declaration means. Casual Make provides the command
~casual-make-identify-autovar-region~ to identify a selected automatic variable
via the binding '.' in ~casual-make-tmenu~. A short description of the
automatic variable is shown in the mini-buffer.
+
+** Unicode Symbol Support
+By enabling “Use Unicode Symbols” from the Settings menu, Casual Make will use
Unicode symbols as appropriate in its menus.
+
+* Sponsorship
+If you enjoy using Casual Make, consider making a modest financial
contribution to help support its development and maintenance.
+
+[[https://www.buymeacoffee.com/kickingvegas][file:images/default-yellow.png]]
+
+* See Also
+- [[file:agenda.org][Agenda]]
+- [[file:bookmarks.org][Bookmarks]]
+- [[file:calc.org][Calc]]
+- [[file:calendar.org][Calendar]]
+- [[file:dired.org][Dired]]
+- [[file:editkit.org][EditKit (numerous editing commands)]]
+- [[file:ibuffer.org][IBuffer]]
+- [[file:image.org][Image]]
+- [[file:info.org][Info]]
+- [[file:isearch.org][I-Search]]
+- [[file:re-builder.org][RE-Builder]]
diff --git a/lisp/Makefile b/lisp/Makefile
index 70436c76be..3e6d5d8623 100644
--- a/lisp/Makefile
+++ b/lisp/Makefile
@@ -28,9 +28,9 @@ editkit-tests \
ibuffer-tests \
info-tests \
isearch-tests \
+make-mode-tests \
re-builder-tests
-
.PHONY: lib-tests
lib-tests:
$(MAKE) -C $(SRC_DIR) -f Makefile-lib.make tests
@@ -75,6 +75,10 @@ info-tests:
isearch-tests:
$(MAKE) -C $(SRC_DIR) -f Makefile-isearch.make tests
+.PHONY: make-mode-tests
+make-mode-tests:
+ $(MAKE) -C $(SRC_DIR) -f Makefile-make-mode.make tests
+
.PHONY: re-builder-tests
re-builder-tests:
$(MAKE) -C $(SRC_DIR) -f Makefile-re-builder.make tests
diff --git a/lisp/Makefile-make-mode.make b/lisp/Makefile-make-mode.make
new file mode 100644
index 0000000000..f567e868f0
--- /dev/null
+++ b/lisp/Makefile-make-mode.make
@@ -0,0 +1,30 @@
+##
+# Copyright (C) 2025 Charles Y. Choi
+#
+# 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/>.
+
+include Makefile--defines.make
+
+PACKAGE_NAME=casual-make
+ELISP_INCLUDES=casual-make-utils.el \
+casual-make-settings.el
+ELISP_PACKAGES=
+ELISP_TEST_INCLUDES=casual-make-test-utils.el
+PACKAGE_PATHS= \
+-L $(EMACS_ELPA_DIR)/compat-current \
+-L $(EMACS_ELPA_DIR)/seq-current \
+-L $(EMACS_ELPA_DIR)/transient-current \
+-L $(CASUAL_LIB_LISP_DIR)
+
+include Makefile--rules.make
diff --git a/lisp/casual-editkit-utils.el b/lisp/casual-editkit-utils.el
index 1cbe723bc6..5e2fc56f19 100644
--- a/lisp/casual-editkit-utils.el
+++ b/lisp/casual-editkit-utils.el
@@ -278,7 +278,7 @@ inserting common miscellaneous symbols."
("b" "•" (lambda () (interactive) (insert "•")))
("m" "—" (lambda () (interactive) (insert "—")))
("o" "°" (lambda () (interactive) (insert "°")))
- ("?" "¿" (lambda () (interactive) (insert "¿")))
+ ("/" "¿" (lambda () (interactive) (insert "¿")))
("!" "¡" (lambda () (interactive) (insert "¡")))
("p" "¶" (lambda () (interactive) (insert "¶")))
("s" "§" (lambda () (interactive) (insert "§")))
diff --git a/lisp/casual-editkit.el b/lisp/casual-editkit.el
index cf00c99cdd..6487f4df17 100644
--- a/lisp/casual-editkit.el
+++ b/lisp/casual-editkit.el
@@ -48,7 +48,7 @@ It can be used as-is or serve as a template for building a
user-customized menu."
[["File"
("o" "Open›" casual-editkit-open-tmenu)
- ("f" "Open file…" find-file)
+ ("f" "Open file…" find-file-at-point)
("d" "Open in Dired" dired-jump-other-window
:if (lambda () (buffer-file-name)))
("b" "List Buffers" ibuffer)
diff --git a/lisp/casual-make-settings.el b/lisp/casual-make-settings.el
new file mode 100644
index 0000000000..da861b1fc8
--- /dev/null
+++ b/lisp/casual-make-settings.el
@@ -0,0 +1,75 @@
+;;; casual-make-settings.el --- Casual Make Settings -*- lexical-binding: t;
-*-
+
+;; Copyright (C) 2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+;;
+
+;;; Code:
+(require 'make-mode)
+(require 'casual-lib)
+
+(transient-define-prefix casual-make-settings-tmenu ()
+ "Casual Make settings menu."
+ ["Make: Settings"
+ ["Customize"
+ ("G" "Makefile Group" casual-make--customize-group)
+ (casual-lib-customize-unicode)
+ (casual-lib-customize-hide-navigation)]]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ ("a" "About" casual-make-about :transient nil)
+ (casual-lib-quit-all)])
+
+(defun casual-make--customize-group ()
+ "Customize Makefile group."
+ (interactive)
+ (customize-group "makefile"))
+
+(defun casual-make-about-make ()
+ "Casual Make is a Transient menu for makefiles.
+
+Learn more about using Casual Make at our discussion group on GitHub.
+Any questions or comments about it should be made there.
+URL `https://github.com/kickingvegas/casual/discussions'
+
+If you find a bug or have an enhancement request, please file an issue.
+Our best effort will be made to answer it.
+URL `https://github.com/kickingvegas/casual/issues'
+
+If you enjoy using Casual Make, consider making a modest financial
+contribution to help support its development and maintenance.
+URL `https://www.buymeacoffee.com/kickingvegas'
+
+Casual Make was conceived and crafted by Charles Choi in
+San Francisco, California.
+
+Thank you for using Casual Make.
+
+Always choose love."
+ (ignore))
+
+(defun casual-make-about ()
+ "About information for Casual Make."
+ (interactive)
+ (describe-function #'casual-make-about-make))
+
+(provide 'casual-make-settings)
+;;; casual-make-settings.el ends here
diff --git a/lisp/casual-make-utils.el b/lisp/casual-make-utils.el
new file mode 100644
index 0000000000..2134b71d6d
--- /dev/null
+++ b/lisp/casual-make-utils.el
@@ -0,0 +1,239 @@
+;;; casual-make-utils.el --- Casual Make Utils -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+;;
+
+;;; Code:
+(require 'map)
+(require 'make-mode)
+(require 'casual-lib)
+
+(defconst casual-make-unicode-db
+ '((:previous . '("↑" "Previous"))
+ (:next . '("↓" "Next")))
+
+ "Unicode symbol DB to use for Make Transient menus.")
+
+(defun casual-make-unicode-get (key)
+ "Lookup Unicode symbol for KEY in DB.
+
+- KEY symbol used to lookup Unicode symbol in DB.
+
+If the value of customizable variable `casual-lib-use-unicode'
+is non-nil, then the Unicode symbol is returned, otherwise a
+plain ASCII-range string."
+ (casual-lib-unicode-db-get key casual-make-unicode-db))
+
+
+(defconst casual-make--make-mode-label-map
+ '((makefile-automake-mode . "automake")
+ (makefile-bsdmake-mode . "BSD make")
+ (makefile-gmake-mode . "GNU make")
+ (makefile-imake-mode . "imake")
+ (makefile-mode . "make")
+ (makefile-makepp-mode . "makepp"))
+ "Map of make modes to their labels.")
+
+(defun casual-make-mode-label (mode)
+ "Label for make MODE."
+ (map-elt casual-make--make-mode-label-map mode))
+
+(transient-define-prefix casual-make-mode-select-tmenu ()
+ "Configure `make-mode' for different variants of Make."
+
+ ["Select Make Mode"
+ :description (lambda ()
+ (format
+ "Select Make Mode (%s)"
+ (casual-make-mode-label major-mode)))
+ [("a" "automake" makefile-automake-mode)
+ ("b" "BSD make" makefile-bsdmake-mode)
+ ("g" "GNU make" makefile-gmake-mode)]
+ [("i" "imake" makefile-imake-mode)
+ ("m" "make" makefile-mode)
+ ("e" "makepp" makefile-makepp-mode)]]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ (casual-lib-quit-all)])
+
+(defconst casual-make--autovar-description-map
+ '(("$@" . "The target name.")
+ ("$(@D)" . "The directory part of the target.")
+ ("$(@F)" . "The file-within-directory part of the target.")
+ ("$*" . "Stem with which an implicit rule matches.")
+ ("$(*D)" . "Directory part of stem.")
+ ("$(*F)" . "File-within-directory part of stem.")
+ ("$%" . "The target member name, when the target is an archive member.")
+ ("$(%D)" . "The directory part of the target archive member name.")
+ ("$(%F)" . "The file-within-directory part of the target archive member
name.")
+ ("$<" . "The name of the first prerequisite.")
+ ("$(<D)" . "The directory part of the first prerequisite.")
+ ("$(<F)" . "The file-within-directory part of the first prerequisite.")
+ ("$?" . "The names of all the prerequisites that are newer than the
target.")
+ ("$(?D)" . "Lists of the directory parts of all prerequisites newer than
the target.")
+ ("$(?F)" . "Lists of the file-within-directory parts of all prerequisites
newer than the target.")
+ ("$^" . "The names of all prerequisites, normalized (de-duplicated).")
+ ("$(^D)" . "Lists of the directory parts of all prerequisites,
normalized.")
+ ("$(^F)" . "Lists of the file-within-directory parts of all prerequisites,
normalized.")
+ ("$+" . "The names of all prerequisites, allowing duplicates.")
+ ("$(+D)" . "Lists of the directory parts of all prerequisites, allowing
duplicates.")
+ ("$(+F)" . "Lists of the file-within-directory parts of all prerequisites,
allowing duplicates."))
+ "Map of automatic variable descriptions.")
+
+(defun casual-make--identify-autovar (value)
+ "Identify GNU Make automatic variable in VALUE."
+ (let* ((value (string-clean-whitespace value))
+ (description (map-elt casual-make--autovar-description-map value)))
+ (if description
+ (format "%s - %s" value description)
+ (format "%s is not a GNU Make automatic variable." value))))
+
+(defun casual-make-identify-autovar-region (start end)
+ "Identify GNU Make automatic variable in region from START to END."
+ (interactive "r")
+ (let ((value (buffer-substring start end)))
+ (message (casual-make--identify-autovar value))))
+
+
+;; Transients
+(transient-define-prefix casual-make-automatic-variables-tmenu ()
+ "Makefile automatic variables menu.
+
+Menu for GNU Make automatic variables.
+
+For more info, refer to info node `(make) Automatic Variables'."
+
+ ["Automatic Variables - GNU Make"
+ ["Target @"
+ :pad-keys t
+ ("$@" "Name"
+ (lambda ()
+ "The target name."
+ (interactive) (insert "$@")))
+ ("$(@D)" "Directory"
+ (lambda ()
+ "The directory part of the target."
+ (interactive) (insert "$(@D)")))
+ ("$(@F)" "File"
+ (lambda ()
+ "The file-within-directory part of the target."
+ (interactive) (insert "$(@F)")))]
+
+ ["Implicit Stem *"
+ :pad-keys t
+ ("$*" "Stem"
+ (lambda ()
+ "Stem with which an implicit rule matches."
+ (interactive) (insert "$*")))
+ ("$(*D)" "Directory"
+ (lambda ()
+ "Directory part of stem."
+ (interactive) (insert "$(*D)")))
+ ("$(*F)" "File"
+ (lambda ()
+ "File-within-directory part of stem."
+ (interactive) (insert "$(*F)")))]
+
+ ["Archive %"
+ :pad-keys t
+ ("$%" "Archive"
+ (lambda ()
+ "The target member name, when the target is an archive member."
+ (interactive) (insert "$%")))
+ ("$(%D)" "Directory"
+ (lambda ()
+ "The directory part of the target archive member name."
+ (interactive) (insert "$(%D)")))
+ ("$(%F)" "File"
+ (lambda ()
+ "The file-within-directory part of the target archive member name."
+ (interactive) (insert "$(%F)")))]]
+
+ ["Prerequisites"
+ ["First <"
+ :pad-keys t
+ ("$<" "First"
+ (lambda ()
+ "The name of the first prerequisite."
+ (interactive) (insert "$<")))
+ ("$(<D)" "Directory"
+ (lambda ()
+ "The directory part of the first prerequisite."
+ (interactive) (insert "$(<D)")))
+ ("$(<F)" "File"
+ (lambda ()
+ "The file-within-directory part of the first prerequisite."
+ (interactive) (insert "$(<F)")))]
+
+ ["Newer than Target ?"
+ :pad-keys t
+ ("$?" "All"
+ (lambda ()
+ "The names of all the prerequisites that are newer than the target."
+ (interactive) (insert "$?")))
+ ("$(?D)" "Directory"
+ (lambda ()
+ "Lists of the directory parts of all prerequisites newer than the
target."
+ (interactive) (insert "$(?D)")))
+ ("$(?F)" "File"
+ (lambda ()
+ "Lists of the file-within-dir parts of all prerequisites newer than the
target."
+ (interactive) (insert "$(?F)")))]
+
+ ["Normalized ^"
+ :pad-keys t
+ ("$^" "All"
+ (lambda ()
+ "The names of all prerequisites, normalized (de-duplicated)."
+ (interactive) (insert "$^")))
+ ("$(^D)" "Directory"
+ (lambda ()
+ "Lists of the directory parts of all prerequisites, normalized."
+ (interactive) (insert "$(^D)")))
+ ("$(^F)" "File"
+ (lambda ()
+ "Lists of the file-within-directory parts of all prerequisites,
normalized."
+ (interactive) (insert "$(^F)")))]
+
+ ["Include Duplicates +"
+ :pad-keys t
+ ("$+" "All"
+ (lambda ()
+ "The names of all prerequisites, allowing duplicates."
+ (interactive) (insert "$+")))
+ ("$(+D)" "Directory"
+ (lambda ()
+ "Lists of the directory parts of all prerequisites, allowing
duplicates."
+ (interactive) (insert "$(+D)")))
+ ("$(+F)" "File"
+ (lambda ()
+ "Lists of the file-within-dir parts of all prerequisites, allowing
duplicates."
+ (interactive) (insert "$(+F)")))]]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ (casual-lib-quit-all)
+ ("RET" "Dismiss" casual-lib-quit-all)
+ ("i" "Info" (lambda () (interactive) (info "(make) Automatic Variables")))])
+
+(provide 'casual-make-utils)
+;;; casual-make-utils.el ends here
diff --git a/lisp/casual-make.el b/lisp/casual-make.el
new file mode 100644
index 0000000000..f239b47429
--- /dev/null
+++ b/lisp/casual-make.el
@@ -0,0 +1,85 @@
+;;; casual-make.el --- Transient UI for Make -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+
+;; This library provides a Transient-based user interface for `make-mode'.
+
+;;
+;; INSTALLATION
+
+;; In your initialization file, bind the Transient `casual-make-tmenu' to your
+;; key binding of preference. Two suggested bindings are 'M-m' and 'C-c m'.
+
+;; (require 'casual-make) ; optional if using autoloaded menu
+;; (keymap-set makefile-mode-map "M-m" #'casual-make-tmenu)
+
+;;; Code:
+(require 'casual-make-utils)
+(require 'casual-make-settings)
+
+;;;###autoload (autoload 'casual-make-tmenu "casual-make" nil t)
+(transient-define-prefix casual-make-tmenu ()
+ "Main menu for Casual Make.
+
+This menu provides a user interface for the commands in `make-mode'."
+
+ ["Casual Make"
+ :description (lambda () (format "Casual Make (%s)" (casual-make-mode-label
major-mode)))
+ ["Edit"
+ :inapt-if (lambda () (if buffer-read-only t nil))
+ ("\\" "Backslash region" makefile-backslash-region :inapt-if-not
use-region-p)
+ (";" "Comment region" comment-region :inapt-if-not use-region-p)
+ (":" "Insert target…" makefile-insert-target-ref)
+ ("m" "Insert macro…" makefile-insert-macro-ref)
+ ("f" "Insert GNU function…" makefile-insert-gmake-function)
+ ("a" "Automatic Variables›" casual-make-automatic-variables-tmenu)]
+
+ ["Pickup as targets"
+ ("E" "Everything" makefile-pickup-everything)
+ ("F" "Filenames" makefile-pickup-filenames-as-targets)]
+
+ ["Misc"
+ ("c" "Compile…" compile)
+ ("o" "Overview" makefile-create-up-to-date-overview)
+ ("t" "Makefile Type›" casual-make-mode-select-tmenu :transient t)
+ ("." "Identify Auto Var" casual-make-identify-autovar-region
+ :inapt-if-not use-region-p)]
+
+ ["Navigate"
+ ("i" "Index Menu…" imenu :transient t)
+ ("p" "Previous" makefile-previous-dependency
+ :description (lambda ()
+ (format "%s target" (casual-make-unicode-get :previous)))
+ :transient t)
+ ("n" "Next" makefile-next-dependency
+ :description (lambda ()
+ (format "%s target"(casual-make-unicode-get :next)))
+ :transient t)]]
+
+ [:class transient-row
+ (casual-lib-quit-one)
+ ("," "Settings" casual-make-settings-tmenu)
+ ("I" "ⓘ Make" (lambda () (interactive) (info "(make) Top")))
+ (casual-lib-quit-all)
+ ("RET" "Exit Menu" transient-quit-all)])
+
+(provide 'casual-make)
+;;; casual-make.el ends here
diff --git a/lisp/casual.el b/lisp/casual.el
index 49d5ee78ae..c082a52912 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.3.2
+;; Version: 2.3.3-rc.1
;; Package-Requires: ((emacs "29.1") (transient "0.6.0"))
;; This program is free software; you can redistribute it and/or modify
@@ -74,6 +74,10 @@
;; An interface for the many commands supported by I-Search.
;; URL: `https://github.com/kickingvegas/casual/blob/main/docs/isearch.org'
+;; - Make (Elisp library: `casual-make')
+;; An interface to `make-mode'.
+;; URL: `https://github.com/kickingvegas/casual/blob/main/docs/make-mode.org'
+
;; - Re-Builder (Elisp library: `casual-re-builder')
;; An interface for the Emacs regular expression tool.
;; URL:
`https://github.com/kickingvegas/casual/blob/main/docs/re-builder.org'
diff --git a/tests/Makefile b/tests/Makefile
index 46026aad3f..c485160e9d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -27,6 +27,7 @@ editkit-tests \
ibuffer-tests \
info-tests \
isearch-tests \
+make-mode-tests \
re-builder-tests
SRC_DIR=../lisp
@@ -41,6 +42,7 @@ editkit-tests \
ibuffer-tests \
info-tests \
isearch-tests \
+make-mode-tests \
re-builder-tests
lib-tests:
@@ -73,5 +75,8 @@ info-tests:
isearch-tests:
$(MAKE) -C $(SRC_DIR) $@
+make-mode-tests:
+ $(MAKE) -C $(SRC_DIR) $@
+
re-builder-tests:
$(MAKE) -C $(SRC_DIR) $@
diff --git a/tests/casual-make-test-utils.el b/tests/casual-make-test-utils.el
new file mode 100644
index 0000000000..2e57e95a80
--- /dev/null
+++ b/tests/casual-make-test-utils.el
@@ -0,0 +1,70 @@
+;;; casual-make-test-utils.el --- Casual Test Utils -*- lexical-binding:
t; -*-
+
+;; Copyright (C) 2024-2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+
+;;
+
+;;; Code:
+(require 'ert)
+(require 'casual-lib)
+(require 'kmacro)
+
+
+(defun casualt-make-setup (&optional filename)
+ "Casual editkit test with FILENAME.
+
+- FILENAME file name to be stored in /tmp."
+ (when filename
+ (let ((temp-filename (concat "/tmp/" filename)))
+ (with-temp-file temp-filename
+ (insert "# Hello"))
+ (find-file temp-filename))))
+
+(defun casualt-make-breakdown (&optional filename)
+ "Casual menu test breakdown function with FILENAME.
+
+- FILENAME filename that is stored in /tmp"
+
+ (when filename
+ (let ((temp-filename (concat "/tmp/" filename)))
+ (kill-buffer)
+ (delete-file temp-filename))))
+
+
+(defun casualt-mock-active-region ()
+ "Mock an active region to test `use-region-p'."
+
+ (let ((p1 (line-beginning-position)))
+ (transient-mark-mode t)
+
+ (push-mark p1)
+ (insert "hey: mary\n")
+ (insert "jane\n")
+ (insert "bob\n")
+
+ (goto-char (line-end-position))
+ (setq mark-active t)
+ ))
+
+
+
+(provide 'casual-make-test-utils)
+;;; casual-make-test-utils.el ends here
diff --git a/tests/test-casual-editkit-utils.el
b/tests/test-casual-editkit-utils.el
index c845a84243..504cef3f50 100644
--- a/tests/test-casual-editkit-utils.el
+++ b/tests/test-casual-editkit-utils.el
@@ -82,7 +82,7 @@
(let ((test-vectors
'((:binding "f" :command project-find-file)
- (:binding "BC-g" :command project-switch-to-buffer)
+ (:binding "Bcasual
" :command project-switch-to-buffer)
(:binding "d" :command project-dired)
(:binding "D" :command project-find-dir)
(:binding "v" :command project-vc-dir)
@@ -142,9 +142,9 @@
(let ((tmpfile "casual-editkit-emoji-symbols-tmenu.txt"))
(casualt-editkit-setup tmpfile)
(emacs-lisp-mode)
- (cl-letf ()
+ (cl-letf ((casualt-mock #'emoji-search))
(let ((test-vectors
- '((:binding "e" :command emoji-search)
+ '((:binding "e😀" :command emoji-search)
(:binding "l" :command emoji-list)
(:binding "d" :command emoji-describe)
(:binding "+" :command emoji-zoom-increase)
@@ -524,7 +524,7 @@
(:binding "a" :command calendar)
(:binding "C" :command world-clock)
(:binding "S" :command sunrise-sunset)
- (:binding "E" :command erc)
+ (:binding "E
y" :command erc)
(:binding "M-e" :command eww)
(:binding "z" :command zone)
(:binding "T" :command tetris))))
diff --git a/tests/test-casual-editkit.el b/tests/test-casual-editkit.el
index 5d0ecff5b9..d6417df292 100644
--- a/tests/test-casual-editkit.el
+++ b/tests/test-casual-editkit.el
@@ -35,7 +35,7 @@
((symbol-function
#'casual-editkit-package-symbol-overlay-installed-p) (lambda () t))
((symbol-function #'casual-editkit-package-magit-installed-p)
(lambda () t))
((symbol-function #'display-graphic-p) (lambda (&optional d) t))
- (casualt-mock #'find-file)
+ (casualt-mock #'find-file-at-point)
(casualt-mock #'dired-jump-other-window)
(casualt-mock #'ibuffer)
(casualt-mock #'recentf-open-files)
@@ -63,7 +63,7 @@
(let ((test-vectors
'((:binding "o" :command casual-editkit-open-tmenu)
- (:binding "f" :command find-file)
+ (:binding "f" :command find-file-at-point)
(:binding "d" :command dired-jump-other-window)
(:binding "b" :command ibuffer)
(:binding "R" :command recentf-open-files)
diff --git a/tests/test-casual-make-settings.el
b/tests/test-casual-make-settings.el
new file mode 100644
index 0000000000..2e0306a7fe
--- /dev/null
+++ b/tests/test-casual-make-settings.el
@@ -0,0 +1,52 @@
+;;; test-casual-make-settings.el --- Casual Make Settings Tests -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+
+;;
+
+;;; Code:
+
+(require 'ert)
+(require 'casual-make-test-utils)
+(require 'casual-make-settings)
+
+(ert-deftest test-casual-make-settings-tmenu ()
+ (let ((tmpfile "casual-make-settings-tmenu.txt"))
+ (casualt-make-setup)
+ (cl-letf (;;((symbol-function #') (lambda () t))
+ (casualt-mock #'casual-make--customize-group))
+
+ (let ((test-vectors
+ '((:binding "G" :command casual-make--customize-group)
+ (:binding "u" :command
casual-lib-customize-casual-lib-use-unicode)
+ (:binding "n" :command
casual-lib-customize-casual-lib-hide-navigation)
+ (:binding "a" :command casual-make-about))))
+
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-make-settings-tmenu
+ '(lambda () (random 5000)))))
+ (casualt-make-breakdown)))
+
+(ert-deftest test-casual-make-about ()
+ (should (stringp (casual-make-about))))
+
+(provide 'test-casual-make-settings)
+;;; test-casual-make-setttings.el ends here
diff --git a/tests/test-casual-make-utils.el b/tests/test-casual-make-utils.el
new file mode 100644
index 0000000000..e1d4e2ec17
--- /dev/null
+++ b/tests/test-casual-make-utils.el
@@ -0,0 +1,90 @@
+;;; test-casual-make-utils.el --- Casual Make Utils Tests -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+
+;;
+
+;;; Code:
+(require 'ert)
+(require 'casual-make-test-utils)
+(require 'casual-make-utils)
+
+(ert-deftest test-casual-make-unicode-get ()
+ (let ((casual-lib-use-unicode nil))
+ (should (string-equal (casual-make-unicode-get :previous) "Previous"))
+ (should (string-equal (casual-make-unicode-get :next) "Next")))
+
+ (let ((casual-lib-use-unicode t))
+ (should (string-equal (casual-make-unicode-get :previous) "↑"))
+ (should (string-equal (casual-make-unicode-get :next) "↓"))))
+
+
+(ert-deftest test-casual-make-mode-select-tmenu ()
+ (let ((tmpfile "casual-make-mode-select-tmenu.txt"))
+ (casualt-make-setup)
+ (cl-letf ((casualt-mock #'makefile-automake-mode)
+ (casualt-mock #'makefile-bsdmake-mode)
+ (casualt-mock #'makefile-gmake-mode)
+ (casualt-mock #'makefile-imake-mode)
+ (casualt-mock #'makefile-mode)
+ (casualt-mock #'makefile-makepp-mode))
+
+ (let ((test-vectors
+ '((:binding "a" :command makefile-automake-mode)
+ (:binding "b" :command makefile-bsdmake-mode)
+ (:binding "g" :command makefile-gmake-mode)
+ (:binding "i" :command makefile-imake-mode)
+ (:binding "m" :command makefile-mode)
+ (:binding "e" :command makefile-makepp-mode))))
+
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-make-mode-select-tmenu
+ '(lambda () (random 5000)))))
+ (casualt-make-breakdown)))
+
+
+(ert-deftest test-casual-make--autovar-description-map ()
+ (let ((avmap casual-make--autovar-description-map))
+ (should (string= (map-elt avmap "$@") "The target name."))
+ (should (string= (map-elt avmap "$(@D)") "The directory part of the
target."))
+ (should (string= (map-elt avmap "$(@F)") "The file-within-directory part
of the target."))
+ (should (string= (map-elt avmap "$*") "Stem with which an implicit rule
matches."))
+ (should (string= (map-elt avmap "$(*D)") "Directory part of stem."))
+ (should (string= (map-elt avmap "$(*F)") "File-within-directory part of
stem."))
+ (should (string= (map-elt avmap "$%") "The target member name, when the
target is an archive member."))
+ (should (string= (map-elt avmap "$(%D)") "The directory part of the target
archive member name."))
+ (should (string= (map-elt avmap "$(%F)") "The file-within-directory part
of the target archive member name."))
+ (should (string= (map-elt avmap "$<") "The name of the first
prerequisite."))
+ (should (string= (map-elt avmap "$(<D)") "The directory part of the first
prerequisite."))
+ (should (string= (map-elt avmap "$(<F)") "The file-within-directory part
of the first prerequisite."))
+ (should (string= (map-elt avmap "$?") "The names of all the prerequisites
that are newer than the target."))
+ (should (string= (map-elt avmap "$(?D)") "Lists of the directory parts of
all prerequisites newer than the target."))
+ (should (string= (map-elt avmap "$(?F)") "Lists of the
file-within-directory parts of all prerequisites newer than the target."))
+ (should (string= (map-elt avmap "$^") "The names of all prerequisites,
normalized (de-duplicated)."))
+ (should (string= (map-elt avmap "$(^D)") "Lists of the directory parts of
all prerequisites, normalized."))
+ (should (string= (map-elt avmap "$(^F)") "Lists of the
file-within-directory parts of all prerequisites, normalized."))
+ (should (string= (map-elt avmap "$+") "The names of all prerequisites,
allowing duplicates."))
+ (should (string= (map-elt avmap "$(+D)") "Lists of the directory parts of
all prerequisites, allowing duplicates."))
+ (should (string= (map-elt avmap "$(+F)") "Lists of the
file-within-directory parts of all prerequisites, allowing duplicates."))))
+
+
+(provide 'test-casual-make-utils)
+;;; test-casual-make-utils.el ends here
diff --git a/tests/test-casual-make.el b/tests/test-casual-make.el
new file mode 100644
index 0000000000..a45310dab4
--- /dev/null
+++ b/tests/test-casual-make.el
@@ -0,0 +1,75 @@
+;;; test-casual-make.el --- Casual Make Tests -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Charles Y. Choi
+
+;; Author: Charles Choi <[email protected]>
+;; Keywords: tools
+
+;; 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:
+
+;;
+
+;;; Code:
+
+(require 'ert)
+(require 'casual-make-test-utils)
+(require 'casual-lib-test-utils)
+(require 'casual-make)
+
+(ert-deftest test-casual-make-tmenu ()
+ (let ((tmpfile "Makefile"))
+ (casualt-make-setup tmpfile)
+ (cl-letf ((casualt-mock #'makefile-backslash-region)
+ (casualt-mock #'comment-region)
+ (casualt-mock #'makefile-insert-target-ref)
+ (casualt-mock #'makefile-insert-macro-ref)
+ (casualt-mock #'makefile-insert-gmake-function)
+ (casualt-mock #'makefile-pickup-everything)
+ (casualt-mock #'makefile-pickup-filenames-as-targets)
+ (casualt-mock #'makefile-create-up-to-date-overview)
+ (casualt-mock #'makefile-previous-dependency)
+ (casualt-mock #'makefile-next-dependency)
+ (casualt-mock #'compile)
+ (casualt-mock #'imenu))
+
+ (let ((test-vectors
+ '((:binding "\\" :command makefile-backslash-region)
+ (:binding ";" :command comment-region)
+ (:binding ":" :command makefile-insert-target-ref)
+ (:binding "m" :command makefile-insert-macro-ref)
+ (:binding "f" :command makefile-insert-gmake-function)
+ (:binding "a" :command casual-make-automatic-variables-tmenu)
+
+ (:binding "E" :command makefile-pickup-everything)
+ (:binding "F" :command makefile-pickup-filenames-as-targets)
+
+ (:binding "c" :command compile)
+ (:binding "o" :command makefile-create-up-to-date-overview)
+ (:binding "t" :command casual-make-mode-select-tmenu)
+ (:binding "." :command casual-make-identify-autovar-region)
+
+ ;; (:binding "i" :command imenu)
+ (:binding "p" :command makefile-previous-dependency)
+ (:binding "n" :command makefile-next-dependency))))
+
+ (casualt-mock-active-region)
+ (casualt-suffix-testcase-runner test-vectors
+ #'casual-make-tmenu
+ '(lambda () (random 5000)))))
+ (casualt-make-breakdown tmpfile)))
+
+(provide 'test-casual-make)
+;;; test-casual-make.el ends here