[Help] Fixing homemade snippet system (Skeletons + Abbrevs

https://lemmy.world/post/1788525

[Help] Fixing homemade snippet system (Skeletons + Abbrevs - Lemmy.world

Hey gang, So initially I had something pretty simple to have “snippets” in my Emacs config, using Skeletons and Abbrevs. I’ve expanded on it a little bit since then, but I’m running into an issue where the abbrev no longer expands to call the skeleton function. Here’s what I have: emacs-lisp ;;;###autoload (defun abbrev::abbrev-table-add-props (abbrev-table props) "Add one or more PROPS to an existing ABBREV-TABLE. PROPS should be a plist of (PROP VALUE). Example: (:enable-function (lambda (&rest _) (do-something)))" (if (cddr props) (cl-loop for (k v) on props by #'cddr unless (not (abbrev-table-p abbrev-table)) unless (abbrev-table-get abbrev-table k) do (abbrev-table-put abbrev-table k v)) (unless (and (not (abbrev-table-p abbrev-table)) (abbrev-table-get abbrev-table (car props))) (abbrev-table-put abbrev-table (car props) (cadr props))))) ;;;###autoload (defmacro def-mode-snippet (name mode docstring &rest prompt-and-or-skeleton) "Create a MODES specific \"snippet\" with NAME and SKELETON. NAME must be valid in the Emacs Lisp naming convention. MODE must be a valid major or minor mode that is known to Emacs. Example: ‘org-mode’, ‘emacs-lisp-mode’, etc. DOCSTRING is used in the abbrev rather than the skeleton. PROMPT-AND-OR-SKELETON can be any of the following: 1. A valid Skeleton that uses the internal `Skeleton' langauge 2. A key/value \"pair\" that’s :prompt STRING, followed by a valid Skeleton that uses the internal `Skeleton' language. The prompt given is used by the Skeleton to prompt the user for an input. This macro makes use of `define-skeleton' and `define-abbrev' in order to create something similar to a code/writing snippet system, like that of `YASnippet'. Keep in mind that all abbreviations created are put in the abbrev table of MODE you passed to this macro. Example: passing ‘org-mode’ will add the abbrev to the ‘org-mode-abbrev-table’. That may or may not be something you want depending on your uses. If you're looking to only define an abbrev globally, see `def-global-snippet'." (declare (debug t) (doc-string 3) (indent defun)) ;; TODO need to figure out how to work with lists better (let* ((snip-name (symbol-name `,name)) (func-name (intern (concat (symbol-name mode) "-" snip-name "-skel"))) (var-str (concat (symbol-name mode) "-abbrev-table")) (abbrev-table (intern-soft var-str)) (has-prompt (keywordp (car prompt-and-or-skeleton))) (prompt (if has-prompt (cadr prompt-and-or-skeleton) nil)) (skeleton (if (not has-prompt) prompt-and-or-skeleton (cddr prompt-and-or-skeleton))) ;; Not using this for now until the issue with abbrevs not expanding is solved. ;;(enable-fn (lambda (&rest _) (or (eq major-mode 'mode) (numberp (cl-position 'mode minor-mode-list))))) ) (macroexp-progn `((define-skeleton ,func-name ,(format "%s %s %s %s." snip-name "skeleton. Defined in" var-str "abbreviaton table") ,prompt ,@skeleton) ,(if (not (abbrev-table-p abbrev-table)) `(define-abbrev ,abbrev-table ,snip-name ',func-name) `(define-abbrev-table ',abbrev-table '((,snip-name ',func-name)) ,(format "An abbrev table for %s" mode) :system t :case-fixed t) (abbrev::abbrev-table-add-props ,abbrev-table '(:system t :case-fixed t))))))) The example I can give is the following: emacs-lisp (def-mode-snippet defun emacs-lisp-mode "defun snippet for Emacs Lisp" > "(defun " @ - " (" @ _ ")" \n > -2 "\"" @ _ "\"" \n > -1 @ _ ")") And that will macro-expand to: emacs-lisp (progn (define-skeleton emacs-lisp-mode-defun-skel "defun skeleton. Defined in emacs-lisp-mode-abbrev-table abbreviaton table." nil > "(defun " @ - " (" @ _ ")" n > -2 "\"" @ _ "\"" n > -1 @ _ ")") (define-abbrev emacs-lisp-mode-abbrev-table "defun" 'emacs-lisp-mode-defun-skel)) Which evals fine, even though I think the n would not be valid to Skeleton, but I’m not sure.

If it helps, I’m on the developer version of Emacs (30). Another weird thing is that I get no errors and the abbrev is listed when running M-x list-abbrevs. The only error I see is when trying to do hippie-expand on the abbrev when it’s typed out gives me:

he-string-member: Wrong type argument: sequencep, emacs-lisp-mode-defun-skel

So maybe this is an issue with the commit of the developer version I’m on? I really don’t know at this point. And before anyone asks, yes, abbrev-mode is on. 😆