branch: externals/cus-abbrev
commit c67e9607d8b84f562a92b659e6accd07db83c992
Author: Mauro Aranda <[email protected]>
Commit: Mauro Aranda <[email protected]>
Initial commit
---
.gitignore | 34 ++++++++
Makefile | 50 +++++++++++
README.md | 33 +++++++
cus-abbrev.el | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 387 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..1c689bc6e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+# Files for Git to ignore.
+
+# Copyright 2025 Mauro Aranda
+
+# This file is part of cus-abbrev.
+
+# cus-abbrev 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.
+
+# cus-abbrev 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 cus-abbrev. If not, see <https://www.gnu.org/licenses/>.
+
+# Logs and temp.
+*.log
+*.tmp
+
+# Patches
+*.patch
+
+# Junk
+*~
+.#*
+\#*\#
+
+# Compiled ELisp
+*.elc
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..52608ceba4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,50 @@
+# Copyright (C) 2025 Mauro Aranda
+
+# This file is part of cus-abbrev.
+
+# cus-abbrev 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.
+
+# cus-abbrev 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 cus-abbrev. If not, see <https://www.gnu.org/licenses/>.
+
+## Programs used.
+EMACS = emacs
+EMACSFLAGS = -batch -f batch-byte-compile
+
+## Variables (some might not be used right now).
+PACKAGE = cus-abbrev
+PACKAGE_BUGREPORT = [email protected]
+PACKAGE_NAME = cus-abbrev
+PACKAGE_STRING = cus-abbrev 1.0
+PACKAGE_TARNAME = cus-abbrev-1.0
+PACKAGE_VERSION = 1.0
+DISTDIR = $(PACKAGE_TARNAME)
+DISTFILES = Makefile cus-abbrev.el
+
+## Targets.
+
+.PHONY: all clean dist
+
+all: cus-abbrev.elc
+
+cus-abbrev.elc: cus-abbrev.el
+ $(EMACS) $(EMACSFLAGS) cus-abbrev.el
+
+clean:
+ -rm -f cus-abbrev.elc
+ -rm -f $(PACKAGE_TARNAME).tar.gz
+
+dist: cus-abbrev.elc
+ mkdir --parents $(DISTDIR)
+ cp --parents $(DISTFILES) $(DISTDIR)
+ tar -cf $(PACKAGE_TARNAME).tar $(DISTDIR)
+ rm -R $(DISTDIR)
+ gzip $(PACKAGE_TARNAME).tar
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..5306c6d20d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# cus-abbrev: Easy Customization for Abbrevs
+
+> Simple package to allow customizations of abbrevs in a Customize-like buffer
+
+## Table of Contents
+
+- [Installation](#installation)
+- [Using](#using)
+- [License](#license)
+
+---
+
+## Installation
+- Download and open up a terminal in the directory.
+- Type `make`.
+- Add the directory to your load path:
+
+Done!
+
+---
+
+## Using
+
+`M-x customize-all-abbrevs`
+
+And just customize what you wish.. Type `C-x C-s` to save.
+
+---
+
+## License
+
+- **[GPL 3](https://www.gnu.org/licenses/gpl-3.0-standalone.html)**
+- Copyright 2023 Mauro Aranda
diff --git a/cus-abbrev.el b/cus-abbrev.el
new file mode 100644
index 0000000000..c45ffe61af
--- /dev/null
+++ b/cus-abbrev.el
@@ -0,0 +1,270 @@
+;;; cus-abbrev.el --- Easy Customization interface for Abbrevs -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Mauro Aranda
+
+;; Author: Mauro Aranda <[email protected]>
+;; Maintainer: Mauro Aranda <[email protected]>
+;; Created: Tue Jan 21 19:59:28 2025
+;; Version: 0.1
+;; Package-Version: 0.1
+;; Package-Requires: ((emacs "28.1"))
+;; URL: https://gitlab.com/mauroaranda/cus-abbrev
+;; Keywords: convenience
+
+;; 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:
+;; The following code provides an Easy Customization interface to manage
+;; abbrevs.
+;; The main command are `customize-abbrevs' and `customize-all-abbrevs'.
+;; It presents a Custom-like buffer with abbrevs to edit.
+
+;;; Code:
+(require 'cus-edit)
+
+(defgroup cus-abbrev nil
+ "Customize Abbrevs with a Customize-like interface."
+ :group 'customize)
+
+(defcustom custom-abbrev-file-name nil
+ "File to use when saving abbrevs.
+
+If nil, this is the same as `abbrev-file-name'."
+ :type '(choice (const :tag "Default abbrev file" nil) (file)))
+
+(defvar-local custom-abbrev-widgets nil
+ "List of widgets that hold the abbrev customizations.")
+
+(defvar-keymap custom-abbrev-map
+ :doc "Keymap used in buffers for Customizing Abbrevs."
+ :full t
+ :parent widget-keymap
+ "SPC" #'scroll-up-command
+ "S-SPC" #'scroll-down-command
+ "DEL" #'scroll-down-command
+ "C-x C-s" #'Custom-abbrev-save
+ "q" #'Custom-buffer-done
+ "n" #'widget-forward
+ "p" #'widget-backward)
+
+(defvar custom-abbrev-commands
+ '((" Save Abbrevs " Custom-abbrev-save t
+ "Save Abbrevs to the abbrevs file." "save" "Save" t)
+ (" Undo Edits " Custom-abbrev-revert-buffer t
+ "Revert buffer, undoing any editions."
+ "refresh" "Undo" t)
+ (" Help for Customize " Custom-help t "Get help for using Customize."
+ "help" "Help" t)
+ (" Exit " Custom-buffer-done t "Exit Customize." "exit" "Exit" t))
+ "Alist of specifications for Customize menu items, tool bar icons and
buttons.
+See `custom-commands' for further explanation.")
+
+(easy-menu-define
+ Custom-abbrev-menu (list custom-abbrev-map)
+ "Menu used in buffers for Customizing Abbrevs."
+ (nconc (list "Custom"
+ (customize-menu-create 'customize))
+ (mapcar (lambda (arg)
+ (let ((tag (nth 0 arg))
+ (command (nth 1 arg))
+ (visible (nth 2 arg))
+ (help (nth 3 arg))
+ (active (nth 6 arg)))
+ (vector tag command :visible (eval visible)
+ :active `(eq t ',active)
+ :help help)))
+ custom-abbrev-commands)))
+
+(defvar custom-abbrev-tool-bar-map nil
+ "Keymap for the toolbar in buffers for Customizing Abbrevs.")
+
+(define-widget 'custom-abbrev 'editable-list
+ "An editable list to edit abbrevs."
+ :entry-format "%i %d %v"
+ :insert-button-args '(:help-echo "Insert new abbrev here.")
+ :append-button-args '(:help-echo "Append new abbrev here.")
+ :delete-button-args '(:help-echo "Delete this abbrev."))
+
+(defun Custom-abbrev-define (&rest _ignored)
+ "Define abbrevs in current buffer, without saving them."
+ (interactive)
+ (dolist (widget custom-abbrev-widgets)
+ (let ((table (symbol-value (widget-get widget :custom-abbrev-table))))
+ (clear-abbrev-table table)
+ (dolist (abbrev-widget (widget-get widget :children))
+ (let ((abbrev (widget-value abbrev-widget)))
+ (define-abbrev table (nth 0 abbrev) (nth 1 abbrev)
+ (nth 2 abbrev)
+ :enable-function (nth 3 abbrev)
+ :case-fixed (nth 4 abbrev))))))
+ (message "Abbrevs defined, but not saved"))
+
+(defun Custom-abbrev-revert-buffer (&rest _ignored)
+ "Revert the buffer for customizing abbrevs."
+ (interactive)
+ (if (>= (length custom-abbrev-widgets) 2)
+ (customize-all-abbrevs)
+ (customize-abbrevs (widget-get (car custom-abbrev-widgets)
+ :custom-abbrev-table))))
+
+(defun Custom-abbrev-save (&rest _ignored)
+ "Save all abbrevs currently being edited.
+
+This command also saves any other editions made to the abbrev table."
+ (interactive)
+ (Custom-abbrev-define)
+ (write-abbrev-file (or custom-abbrev-file-name) abbrev-file-name)
+ (message (format "Abbrevs saved to %s" (or custom-abbrev-file-name
+ abbrev-file-name))))
+
+(defun custom-abbrev--prepare-buffer (buffer-name)
+ "Prepare buffer called BUFFER-NAME for Customizing Abbrevs."
+ (switch-to-buffer buffer-name)
+ (kill-all-local-variables)
+ (let ((inhibit-read-only t))
+ (erase-buffer))
+ (remove-overlays)
+ (custom--initialize-widget-variables))
+
+(defun custom-abbrev--prepare-buffer-2 ()
+ "Finalize preparations for Customizing Abbrevs in current buffer."
+ (goto-char (point-min))
+ (setq-local tool-bar-map
+ (or custom-abbrev-tool-bar-map
+ ;; Set up `custom-abbrev-tool-bar-map'.
+ (let ((map (make-sparse-keymap)))
+ (mapc
+ (lambda (arg)
+ (tool-bar-local-item-from-menu
+ (nth 1 arg) (nth 4 arg) map custom-abbrev-map
+ :label (nth 5 arg)))
+ custom-abbrev-commands)
+ (setq custom-abbrev-tool-bar-map map))))
+ (setq-local revert-buffer-function #'Custom-abbrev-revert-buffer)
+ (use-local-map custom-abbrev-map)
+ (widget-setup))
+
+(defun custom-abbrev--insert-buttons ()
+ "Insert buttons for Customizing Abbrevs in current buffer."
+ (widget-create 'push-button :tag " Revert "
+ :action #'Custom-abbrev-revert-buffer)
+ (widget-insert " ")
+ (widget-create 'push-button :tag " Define Abbrevs "
+ :action #'Custom-abbrev-define)
+ (widget-insert " ")
+ (widget-create 'push-button :tag " Save Abbrevs "
+ :action #'Custom-abbrev-save)
+ (widget-insert "\n\n"))
+
+;;;###autoload
+(defun customize-all-abbrevs ()
+ "Customize all Abbrevs in current session."
+ (interactive)
+ (custom-abbrev--prepare-buffer "*Customize All Abbrevs*")
+ (widget-insert "This buffer is for customizing all Abbrevs.\n")
+ (widget-insert "Check the ")
+ (widget-create 'custom-manual
+ :tag "Abbrev section"
+ "(emacs)Abbrevs")
+ (widget-insert " in the Emacs manual for more information.\n\n")
+ (custom-abbrev--insert-buttons)
+ (dolist (table-name (reverse abbrev-table-name-list))
+ (let ((table (symbol-value table-name))
+ abbrevs)
+ (mapatoms (lambda (abbrev)
+ ;; Guard against ##.
+ (unless (string= (symbol-name abbrev) "")
+ (let ((exp (abbrev-expansion abbrev table)))
+ (when exp
+ (push (list (symbol-name abbrev) exp
+ (symbol-function abbrev)
+ (abbrev-get abbrev :enable-function)
+ (abbrev-get abbrev :case-fixed))
+ abbrevs)))))
+ table)
+ (setq abbrevs (nreverse abbrevs))
+ (push (widget-create 'custom-abbrev
+ :value abbrevs
+ :format "\n%{%t%}\n%v%i\n"
+ :tag (symbol-name table-name)
+ :sample-face 'highlight
+ :custom-abbrev-table table-name
+ '(list :tag "Abbrev"
+ (string :tag "Abbreviation")
+ (string :tag "Expansion")
+ (choice :tag "Hook"
+ (const :tag "None" nil)
+ (function))
+ (choice :tag "Enable function"
+ (const :tag "None" nil)
+ (function :value always))
+ (boolean :tag "Case fixed")))
+ custom-abbrev-widgets)))
+ (custom-abbrev--prepare-buffer-2))
+
+;;;###autoload
+(defun customize-abbrevs (&optional table-name)
+ "Customize Abbrevs in current session for abbrev table TABLE-NAME.
+
+When called interactively, prompts for the abbrev table to customize.
+When called from Lisp, optional argument TABLE-NAME is the symbol that holds
+the abbrev table to customize."
+ (interactive (list
+ (intern-soft
+ (completing-read "Table: "
+ abbrev-table-name-list nil t
+ "global-abbrev-table" nil
+ "global-abbrev-table"))))
+ (let* ((table-name (or table-name 'global-abbrev-table))
+ (table (symbol-value table-name))
+ abbrevs)
+ (mapatoms (lambda (abbrev)
+ (unless (string= (symbol-name abbrev) "")
+ (let ((exp (abbrev-expansion abbrev table)))
+ (when exp
+ (push (list (symbol-name abbrev) exp
+ (symbol-function abbrev)
+ (abbrev-get abbrev :enable-function)
+ (abbrev-get abbrev :case-fixed))
+ abbrevs)))))
+ table)
+ (setq abbrevs (nreverse abbrevs))
+ (custom-abbrev--prepare-buffer "*Customize Abbrevs*")
+ (widget-insert "This buffer is for customizing abbrevs\n")
+ (widget-insert "in abbrev table: ")
+ (widget-create 'variable-link table-name)
+ (widget-insert "\n\nCheck the ")
+ (widget-create 'custom-manual
+ :tag "Abbrev section"
+ "(emacs)Abbrevs")
+ (widget-insert " in the Emacs manual for more information.\n\n")
+ (custom-abbrev--insert-buttons)
+ (setq custom-abbrev-widgets
+ (list
+ (widget-create 'custom-abbrev :value abbrevs
+ :custom-abbrev-table table-name
+ '(list :tag "Abbrev"
+ (string :tag "Abbreviation")
+ (string :tag "Expansion")
+ (choice :tag "Hook"
+ (const :tag "None" nil)
+ (function))
+ (choice :tag "Enable function"
+ (const :tag "None" nil)
+ (function :value always))
+ (boolean :tag "Case fixed"))))))
+ (custom-abbrev--prepare-buffer-2))
+
+(provide 'cus-abbrev)
+;;; cus-abbrev.el ends here