branch: externals/cus-abbrev
commit c67e9607d8b84f562a92b659e6accd07db83c992
Author: Mauro Aranda <maurooara...@gmail.com>
Commit: Mauro Aranda <maurooara...@gmail.com>

    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 = maurooara...@gmail.com
+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 <maurooara...@gmail.com>
+;; Maintainer: Mauro Aranda <maurooara...@gmail.com>
+;; 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

Reply via email to