diff --git a/emacs/.emacs.d/init.el b/emacs/.emacs.d/init.el index 35e1accc..70a8d444 100644 --- a/emacs/.emacs.d/init.el +++ b/emacs/.emacs.d/init.el @@ -381,7 +381,9 @@ DEFINITIONS is a sequence of string and command pairs." (defmacro prot-emacs-abbrev (table &rest definitions) "Expand abbrev DEFINITIONS for the given TABLE. DEFINITIONS is a sequence of string pairs mapping the -abbreviation to its expansion." +abbreviation to its expansion. + +Also see `prot-emacs-abbrev-function'." (declare (indent 1)) (unless (zerop (% (length definitions) 2)) (error "Uneven number of key+command pairs")) @@ -394,6 +396,24 @@ abbreviation to its expansion." `(define-abbrev table ,abbrev ,expansion))) (seq-split definitions 2)))) +(defmacro prot-emacs-abbrev-function (table &rest definitions) + "Expand abbrev DEFINITIONS for the given TABLE. +DEFINITIONS is a sequence of string and function symbol pairs +mapping the abbreviation to its expansion. + +Also see `prot-emacs-abbrev'." + (declare (indent 1)) + (unless (zerop (% (length definitions) 2)) + (error "Uneven number of key+command pairs")) + `(when-let (((abbrev-table-p ,table)) + (table ,table)) + ,@(mapcar + (lambda (pair) + (when-let ((abbrev (car pair)) + (expansion (cadr pair))) + `(define-abbrev table ,abbrev "" ,expansion))) + (seq-split definitions 2)))) + (defun prot-emacs-return-loaded-packages () "Return a list of all loaded packages. Here packages include both `prot-emacs-loaded-packages' and @@ -413,7 +433,7 @@ that is expanded with the `prot-emacs-package' macro." (defconst prot-emacs-font-lock-keywords '(("(\\(prot-emacs-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" (2 font-lock-constant-face nil t)) - ("(\\(prot-emacs-\\(keybind\\|abbrev\\)\\)\\_>[ \t']*\\(\\(\\sw\\|\\s_\\)+\\)?" + ("(\\(prot-emacs-\\(keybind\\|abbrev\\|abbrev-function\\)\\)\\_>[ \t']*\\(\\(\\sw\\|\\s_\\)+\\)?" (3 font-lock-variable-name-face nil t)) ("(\\(prot-emacs-comment\\)\\_>[ \t']*" (1 font-lock-preprocessor-face nil t)))) diff --git a/emacs/.emacs.d/prot-emacs-modules/prot-emacs-completion.el b/emacs/.emacs.d/prot-emacs-modules/prot-emacs-completion.el index e677f27f..4e51621b 100644 --- a/emacs/.emacs.d/prot-emacs-modules/prot-emacs-completion.el +++ b/emacs/.emacs.d/prot-emacs-modules/prot-emacs-completion.el @@ -166,23 +166,49 @@ "texmacs" "TeXmacs" "typescript" "TypeScript" "visavis" "vis-à-vis" - "youtube" "YouTube") + "youtube" "YouTube" + ":up" "🙃" + ":uni" "🦄" + ":laugh" "🤣" + ":smile" "😀" + ":sun" "☀️") + + ;; Allow abbrevs with a prefix colon or underscore. I demonstrated + ;; this here: . + (abbrev-table-put text-mode-abbrev-table :regexp "\\(?:^\\|[\t\s]+\\)\\(?1:[:_].*\\|.*\\)") (with-eval-after-load 'message (prot-emacs-abbrev message-mode-abbrev-table "bestregards" "Best regards,\nProtesilaos (or simply \"Prot\")" "allthebest" "All the best,\nProtesilaos (or simply \"Prot\")" + "niceday" "Have a nice day,\nProtesilaos (or simply \"Prot\")" "abest" "All the best,\nProt" "bregards" "Best regards,\nProt" + "nday" "Have a nice day,\nProt" "nosrht" "P.S. I am phasing out SourceHut: . Development continues on GitHub with GitLab as a mirror.")) + ;; Unlike the above, the `prot-emacs-abbrev-function' macro does not + ;; expand a static text, but calls a function which dynamically + ;; expands into the requisite form. + (require 'prot-abbrev) + (prot-emacs-abbrev-function global-abbrev-table + "metime" #'prot-abbrev-current-time + "medate" #'prot-abbrev-current-date + "mejitsi" #'prot-abbrev-jitsi-link) + ;; message-mode derives from text-mode, so we don't need a separate ;; hook for it. (dolist (hook '(text-mode-hook prog-mode-hook git-commit-mode-hook)) (add-hook hook #'abbrev-mode)) + ;; Because the *scratch* buffer is produced before we load this, we + ;; have to explicitly activate the mode there. + (when-let ((scratch (get-buffer "*scratch*"))) + (with-current-buffer scratch + (abbrev-mode 1))) + ;; By default, abbrev asks for confirmation on whether to use ;; `abbrev-file-name' to save abbrevations. I do not need that, nor ;; do I want it. diff --git a/emacs/.emacs.d/prot-emacs.org b/emacs/.emacs.d/prot-emacs.org index 6d319ff1..40045fe0 100644 --- a/emacs/.emacs.d/prot-emacs.org +++ b/emacs/.emacs.d/prot-emacs.org @@ -1345,7 +1345,9 @@ abbreviations. Though it is good to practice some programming. (defmacro prot-emacs-abbrev (table &rest definitions) "Expand abbrev DEFINITIONS for the given TABLE. DEFINITIONS is a sequence of string pairs mapping the -abbreviation to its expansion." +abbreviation to its expansion. + +Also see `prot-emacs-abbrev-function'." (declare (indent 1)) (unless (zerop (% (length definitions) 2)) (error "Uneven number of key+command pairs")) @@ -1357,6 +1359,24 @@ abbreviation to its expansion." (expansion (cadr pair))) `(define-abbrev table ,abbrev ,expansion))) (seq-split definitions 2)))) + +(defmacro prot-emacs-abbrev-function (table &rest definitions) + "Expand abbrev DEFINITIONS for the given TABLE. +DEFINITIONS is a sequence of string and function symbol pairs +mapping the abbreviation to its expansion. + +Also see `prot-emacs-abbrev'." + (declare (indent 1)) + (unless (zerop (% (length definitions) 2)) + (error "Uneven number of key+command pairs")) + `(when-let (((abbrev-table-p ,table)) + (table ,table)) + ,@(mapcar + (lambda (pair) + (when-let ((abbrev (car pair)) + (expansion (cadr pair))) + `(define-abbrev table ,abbrev "" ,expansion))) + (seq-split definitions 2)))) #+end_src ** The =init.el= to find which packages have been loaded @@ -1402,7 +1422,7 @@ specifies how they should be colourised. (defconst prot-emacs-font-lock-keywords '(("(\\(prot-emacs-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" (2 font-lock-constant-face nil t)) - ("(\\(prot-emacs-\\(keybind\\|abbrev\\)\\)\\_>[ \t']*\\(\\(\\sw\\|\\s_\\)+\\)?" + ("(\\(prot-emacs-\\(keybind\\|abbrev\\|abbrev-function\\)\\)\\_>[ \t']*\\(\\(\\sw\\|\\s_\\)+\\)?" (3 font-lock-variable-name-face nil t)) ("(\\(prot-emacs-comment\\)\\_>[ \t']*" (1 font-lock-preprocessor-face nil t)))) @@ -4080,23 +4100,49 @@ templates to have a real need for it---but it works). "texmacs" "TeXmacs" "typescript" "TypeScript" "visavis" "vis-à-vis" - "youtube" "YouTube") + "youtube" "YouTube" + ":up" "🙃" + ":uni" "🦄" + ":laugh" "🤣" + ":smile" "😀" + ":sun" "☀️") + + ;; Allow abbrevs with a prefix colon or underscore. I demonstrated + ;; this here: . + (abbrev-table-put text-mode-abbrev-table :regexp "\\(?:^\\|[\t\s]+\\)\\(?1:[:_].*\\|.*\\)") (with-eval-after-load 'message (prot-emacs-abbrev message-mode-abbrev-table "bestregards" "Best regards,\nProtesilaos (or simply \"Prot\")" "allthebest" "All the best,\nProtesilaos (or simply \"Prot\")" + "niceday" "Have a nice day,\nProtesilaos (or simply \"Prot\")" "abest" "All the best,\nProt" "bregards" "Best regards,\nProt" + "nday" "Have a nice day,\nProt" "nosrht" "P.S. I am phasing out SourceHut: . Development continues on GitHub with GitLab as a mirror.")) + ;; Unlike the above, the `prot-emacs-abbrev-function' macro does not + ;; expand a static text, but calls a function which dynamically + ;; expands into the requisite form. + (require 'prot-abbrev) + (prot-emacs-abbrev-function global-abbrev-table + "metime" #'prot-abbrev-current-time + "medate" #'prot-abbrev-current-date + "mejitsi" #'prot-abbrev-jitsi-link) + ;; message-mode derives from text-mode, so we don't need a separate ;; hook for it. (dolist (hook '(text-mode-hook prog-mode-hook git-commit-mode-hook)) (add-hook hook #'abbrev-mode)) + ;; Because the *scratch* buffer is produced before we load this, we + ;; have to explicitly activate the mode there. + (when-let ((scratch (get-buffer "*scratch*"))) + (with-current-buffer scratch + (abbrev-mode 1))) + ;; By default, abbrev asks for confirmation on whether to use ;; `abbrev-file-name' to save abbrevations. I do not need that, nor ;; do I want it. @@ -10063,6 +10109,77 @@ Please bear in mind that the code I write here is not necessarily as high quality as what I put in my public packages, meaning that I do not test it as much and do not try to make it perfect. +** The =prot-abbrev.el= library +:PROPERTIES: +:CUSTOM_ID: h:ddb9c32c-2114-4347-9f76-5160e590b5dc +:END: + +#+begin_src emacs-lisp :tangle "prot-lisp/prot-abbrev.el" :mkdirp yes +;;; prot-abbrev.el --- Functions for use with abbrev-mode -*- lexical-binding: t -*- + +;; Copyright (C) 2024 Protesilaos Stavrou + +;; Author: Protesilaos Stavrou +;; URL: https://protesilaos.com/emacs/dotemacs +;; Version: 0.1.0 +;; Package-Requires: ((emacs "30.1")) + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: +;; +;; Functions for use with `abbrev-mode'. +;; +;; Remember that every piece of Elisp that I write is for my own +;; educational and recreational purposes. I am not a programmer and I +;; do not recommend that you copy any of this if you are not certain of +;; what it does. + +;;; Code: + +(defgroup prot-abbrev () + "Functions for use with `abbrev-mode'." + :group 'editing) + +(defcustom prot-abbrev-time-specifier "%R" + "Time specifier for `format-time-string'." + :type 'string + :group 'prot-abbrev) + +(defcustom prot-abbrev-date-specifier "%F" + "Date specifier for `format-time-string'." + :type 'string + :group 'prot-abbrev) + +(defun prot-abbrev-current-time () + "Insert the current time per `prot-abbrev-time-specifier'." + (insert (format-time-string prot-abbrev-time-specifier))) + +(defun prot-abbrev-current-date () + "Insert the current date per `prot-abbrev-date-specifier'." + (insert (format-time-string prot-abbrev-date-specifier))) + +(defun prot-abbrev-jitsi-link () + "Insert a Jitsi link." + (insert (concat "https://meet.jit.si/" (format-time-string "%Y%M%dT%H%M%S")))) + +(provide 'prot-abbrev) +;;; prot-abbrev.el ends here +#+end_src + ** The =prot-coach.el= library :PROPERTIES: :CUSTOM_ID: h:dbdfc774-c389-403f-95e7-17fa62c53d84 diff --git a/emacs/.emacs.d/prot-lisp/prot-abbrev.el b/emacs/.emacs.d/prot-lisp/prot-abbrev.el new file mode 100644 index 00000000..af8e5102 --- /dev/null +++ b/emacs/.emacs.d/prot-lisp/prot-abbrev.el @@ -0,0 +1,63 @@ +;;; prot-abbrev.el --- Functions for use with abbrev-mode -*- lexical-binding: t -*- + +;; Copyright (C) 2024 Protesilaos Stavrou + +;; Author: Protesilaos Stavrou +;; URL: https://protesilaos.com/emacs/dotemacs +;; Version: 0.1.0 +;; Package-Requires: ((emacs "30.1")) + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: +;; +;; Functions for use with `abbrev-mode'. +;; +;; Remember that every piece of Elisp that I write is for my own +;; educational and recreational purposes. I am not a programmer and I +;; do not recommend that you copy any of this if you are not certain of +;; what it does. + +;;; Code: + +(defgroup prot-abbrev () + "Functions for use with `abbrev-mode'." + :group 'editing) + +(defcustom prot-abbrev-time-specifier "%R" + "Time specifier for `format-time-string'." + :type 'string + :group 'prot-abbrev) + +(defcustom prot-abbrev-date-specifier "%F" + "Date specifier for `format-time-string'." + :type 'string + :group 'prot-abbrev) + +(defun prot-abbrev-current-time () + "Insert the current time per `prot-abbrev-time-specifier'." + (insert (format-time-string prot-abbrev-time-specifier))) + +(defun prot-abbrev-current-date () + "Insert the current date per `prot-abbrev-date-specifier'." + (insert (format-time-string prot-abbrev-date-specifier))) + +(defun prot-abbrev-jitsi-link () + "Insert a Jitsi link." + (insert (concat "https://meet.jit.si/" (format-time-string "%Y%M%dT%H%M%S")))) + +(provide 'prot-abbrev) +;;; prot-abbrev.el ends here