changeset 677: | 585f14458a65 |
parent: | ca09f470abb3 |
author: | Richard Westhaver <ellis@rwest.io> |
date: | Tue, 24 Sep 2024 22:19:05 -0400 |
permissions: | -rw-r--r-- |
description: | tweaks |
587 | 1 | ;;; sk.el --- skel Emacs Mode -*- lexical-binding:t -*- |
20 | 2 | |
405 | 3 | ;; skel-mode, skel-minor-mode,skt-minor-mode, sk-classes |
20 | 4 | |
39 | 5 | ;; Copyright (C) 2023 The Compiler Company |
20 | 6 | |
7 | ;; Author: ellis <ellis@rwest.io> |
|
8 | ;; Keywords: languages, lisp |
|
9 | ||
10 | ;; This program is free software; you can redistribute it and/or modify |
|
11 | ;; it under the terms of the GNU General Public License as published by |
|
12 | ;; the Free Software Foundation, either version 3 of the License, or |
|
13 | ;; (at your option) any later version. |
|
14 | ||
15 | ;; This program is distributed in the hope that it will be useful, |
|
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 | ;; GNU General Public License for more details. |
|
19 | ||
20 | ;; You should have received a copy of the GNU General Public License |
|
21 | ;; along with this program. If not, see <https://www.gnu.org/licenses/>. |
|
22 | ||
23 | ;;; Commentary: |
|
24 | ||
421
05e9cbc641dd
break out templates from sk.el to skt.el
Richard Westhaver <ellis@rwest.io>
parents:
406
diff
changeset
|
25 | ;; |
05e9cbc641dd
break out templates from sk.el to skt.el
Richard Westhaver <ellis@rwest.io>
parents:
406
diff
changeset
|
26 | |
20 | 27 | ;;; Code: |
28 | (eval-and-compile (require 'eieio) |
|
29 | (require 'cl-lib) |
|
39 | 30 | (require 'sxp (expand-file-name "sxp.el" (join-paths user-emacs-directory "lib/"))) |
31 | (require 'skeleton) |
|
677 | 32 | (require 'project) |
580
571685ae64f1
queries, cli fixes, dat/csv, emacs org-columns
Richard Westhaver <ellis@rwest.io>
parents:
516
diff
changeset
|
33 | (require 'org) |
39 | 34 | (require 'tempo) |
405 | 35 | (require 'autoinsert) |
20 | 36 | (defvar skel-debug nil) |
37 | (when skel-debug (require 'ede))) |
|
38 | ||
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
39 | (defvar skel-version "0.1.0") |
20 | 40 | |
41 | (defgroup skel nil |
|
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
42 | "skel customization group." |
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
43 | :group 'local) |
20 | 44 | |
405 | 45 | (defcustom skel-minor-mode-map-prefix "C-c C-." |
46 | "Prefix for `skel-minor-mode' keymap." |
|
20 | 47 | :type 'string |
48 | :group 'skel) |
|
49 | ||
50 | (defcustom skel-triggers nil |
|
51 | "Association of symbols to a specific condition which can be used |
|
52 | to trigger `skel-actions' based on the `skel-behavior' value." |
|
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
53 | :type '(list function) |
20 | 54 | :group 'skel) |
55 | ||
56 | (defcustom skel-actions nil |
|
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
57 | "Array of actions which may be performed on skeletons." |
20 | 58 | :type 'obarray |
59 | :group 'skel) |
|
60 | ||
61 | (defcustom skel-id-prefix "sk" |
|
62 | "Default prefix for `make-id'." |
|
63 | :type 'string |
|
64 | :group 'skel) |
|
65 | ||
405 | 66 | (defvar-keymap skel-minor-mode-map |
67 | :doc "skel-minor-mode keymap." |
|
68 | :repeat (:enter) |
|
69 | :prefix 'skel-minor-mode-map) |
|
70 | ||
20 | 71 | (define-minor-mode skel-minor-mode |
405 | 72 | "skel-minor-mode" |
20 | 73 | :global t |
405 | 74 | :lighter " Sk" |
20 | 75 | :group 'skel |
405 | 76 | :keymap skel-minor-mode-map |
421
05e9cbc641dd
break out templates from sk.el to skt.el
Richard Westhaver <ellis@rwest.io>
parents:
406
diff
changeset
|
77 | :version skel-version) |
20 | 78 | |
79 | ;; TODO 2023-09-06: |
|
365
49c3f3d11432
bug fixes and more tweaks for test macros
Richard Westhaver <ellis@rwest.io>
parents:
314
diff
changeset
|
80 | (define-derived-mode skel-mode lisp-mode "SKEL" |
405 | 81 | :group 'skel |
82 | (skel-minor-mode 1)) |
|
20 | 83 | |
516
f68a5996a2b1
skel updates, sketch of sk-path parser
Richard Westhaver <ellis@rwest.io>
parents:
421
diff
changeset
|
84 | (org-babel-make-language-alias "skel" "lisp") |
f68a5996a2b1
skel updates, sketch of sk-path parser
Richard Westhaver <ellis@rwest.io>
parents:
421
diff
changeset
|
85 | |
20 | 86 | (defun maybe-skel-minor-mode () |
87 | "Check the current environment and determine if `skel-minor-mode' should |
|
88 | be enabled. This function is added as a hook to |
|
89 | `lisp-data-mode-hook'.") |
|
90 | ||
91 | (defvar skel-hashtable (make-hash-table :test #'equal) |
|
92 | "Internal table of available skeletons.") |
|
93 | ||
94 | (defvar skel-stack nil "Internal stack of skeletons.") |
|
95 | ||
96 | (defcustom skel-state 'passive |
|
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
97 | "State toggle for the `skel' system. Base states are passive and |
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
98 | active." |
20 | 99 | :type 'symbol |
100 | :group 'skel) |
|
101 | ||
102 | (defvar skel-active-map nil |
|
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
103 | "List of cons cells of the form (SYM . BODY...) where SYM is a member of |
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
104 | `skel-triggers'.") |
20 | 105 | |
106 | (defvar skel-passive-map nil |
|
314
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
107 | "list of cons cells of the form (SYM . BODY...) where SYM is a member of |
5ff2542d5f38
expose compaction pri: #[12604]
Richard Westhaver <ellis@rwest.io>
parents:
40
diff
changeset
|
108 | `skel-triggers'.") |
20 | 109 | |
110 | (defmacro make-id (&optional pre) |
|
111 | `(let ((pre ,(if-let (pre) (concat skel-id-prefix "-" pre "-") (concat skel-id-prefix "-"))) |
|
112 | (current-time-list nil)) |
|
113 | (symb pre (prog1 gensym-counter (setq gensym-counter (1+ gensym-counter))) (format "%x" (car (current-time)))))) |
|
114 | ||
115 | (defmacro defcmd (name &rest body) `(defun ,name nil (interactive) ,@body)) |
|
116 | ||
117 | (defclass sk (sxp) |
|
118 | ((id :initarg :id :initform (make-id))) |
|
119 | :documentation "Base class for skeleton objects. Inherits from `sxp'." |
|
120 | :abstract t) |
|
121 | ||
122 | (defcmd sk-classes (eieio-class-children 'sk)) |
|
123 | ||
124 | (defmacro def-sk-class (name doc &optional slots superclasses) |
|
125 | "Define a new class with superclass of `skel'+SUPERCLASSES, SLOTS, |
|
126 | DOC, and NAME." |
|
127 | (declare (indent 1)) |
|
128 | `(defclass ,(symb "sk-" name) |
|
129 | ,(if superclasses `(sk ,@superclasses) '(sk)) |
|
130 | ,(if slots |
|
131 | `(,@slots |
|
132 | (:id :initarg :id :initform (make-id ,(symbol-name name)) :accessor id)) |
|
133 | `((:id :initarg :id :initform (make-id ,(symbol-name name)) :accessor id))) |
|
134 | :documentation ,doc)) |
|
135 | ||
136 | (def-sk-class target "Target skeleton class.") |
|
137 | (def-sk-class source "Source skeleton class.") |
|
138 | (def-sk-class rule |
|
139 | "Config skeleton class." |
|
140 | ((target :initarg :target :initform nil :type (or null sk-target)) |
|
141 | (rules :initarg :source :initform nil :type (or null sk-source)))) |
|
142 | ||
143 | (def-sk-class project |
|
144 | "Project skeleton class." |
|
145 | ((type :initarg :type :initform nil :accessor sk-project-type :type (or null symbol)) |
|
146 | (rules :initarg :rules :initform nil :accessor sk-project-rules :type list))) |
|
147 | ||
148 | (defun skel-init () |
|
149 | "Initialize the skel library." |
|
150 | (interactive) |
|
151 | (add-to-list 'auto-mode-alist '("skelfile" . skel-mode)) |
|
670
6856c021d084
add dir-locals to skel, fix package lock violation in castable, move .sk files
Richard Westhaver <ellis@rwest.io>
parents:
587
diff
changeset
|
152 | (add-to-list 'auto-mode-alist '("\\.sk" . skel-mode))) |
20 | 153 | |
676
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
154 | (defun project-skelfile-path (&optional project) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
155 | "Find skelfile associated with PROJECT. Defaults to current |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
156 | directory and returns name of skelfile. When PROJECT is T uses |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
157 | `project-current'." |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
158 | (let* ((dir (unless (eql t project) (expand-file-name (or project default-directory)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
159 | (project-root (project-root (project-current nil dir)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
160 | (or |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
161 | (when dir |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
162 | (cl-find-if |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
163 | (lambda (x) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
164 | (when (string-match |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
165 | (rx (or "skelfile" (and (* any) ".sk"))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
166 | (file-name-nondirectory x)) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
167 | x)) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
168 | (directory-files dir t))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
169 | (when project |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
170 | (cl-find-if (lambda (x) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
171 | (when (string-match (rx (or "skelfile" (and (* any) ".sk"))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
172 | (file-name-nondirectory x)) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
173 | x)) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
174 | (directory-files project-root t)))))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
175 | |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
176 | (defun read-skelfile-bind (&optional project) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
177 | (let ((buffer (find-file-noselect (project-skelfile-path project)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
178 | (with-current-buffer buffer |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
179 | (goto-char (point-min)) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
180 | (goto-char (search-forward-regexp (rx bol ":bind" (* space)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
181 | (read buffer)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
182 | |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
183 | (defun project-skelfile-dir-locals (&optional project) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
184 | "Return a list of dir-local bindings from a skelfile." |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
185 | (let ((form (read-skelfile-bind project))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
186 | (cl-loop for f in form |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
187 | do (cond |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
188 | ((eql (car f) :dir-locals) (cl-return (cdr f))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
189 | ;; when used as second element, the first is the name |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
190 | ;; of the CL-local binding, here we discard it and |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
191 | ;; just take the CDDR. |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
192 | ((eql (cadr f) :dir-locals) (cl-return (cddr f))))))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
193 | |
673
e052bac27cec
prep for hacking dir-locals
Richard Westhaver <ellis@rwest.io>
parents:
670
diff
changeset
|
194 | (defun skel-dir-local--get-variables () |
e052bac27cec
prep for hacking dir-locals
Richard Westhaver <ellis@rwest.io>
parents:
670
diff
changeset
|
195 | "Compute and return the list of :DIR-LOCAL bindings found in the current |
e052bac27cec
prep for hacking dir-locals
Richard Westhaver <ellis@rwest.io>
parents:
670
diff
changeset
|
196 | project's skelfile, if any. Typically added to |
e052bac27cec
prep for hacking dir-locals
Richard Westhaver <ellis@rwest.io>
parents:
670
diff
changeset
|
197 | `hack-dir-local--get-variables'." |
676
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
198 | (let ((root (project-root (project-current)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
199 | (cons (expand-file-name root) (project-skelfile-dir-locals root)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
200 | |
677 | 201 | (defun skel-dir-local-get-variables () |
676
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
202 | (let ((root (expand-file-name (project-root (project-current))))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
203 | (unless (assoc-string root dir-locals-class-alist) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
204 | (push (skel-dir-local--get-variables) dir-locals-class-alist)))) |
ca09f470abb3
rm dir-locals and makefile, added dir-locals hacks in sk.el
Richard Westhaver <ellis@rwest.io>
parents:
673
diff
changeset
|
205 | |
677 | 206 | ;; (add-hook 'skel-minor-mode-hook '%skel-dir-local--get-variables) |
673
e052bac27cec
prep for hacking dir-locals
Richard Westhaver <ellis@rwest.io>
parents:
670
diff
changeset
|
207 | |
20 | 208 | (provide 'skel) |
39 | 209 | (provide 'sk) |
210 | ;;; sk.el ends here |