changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > infra > home / .emacs.d/ellis.el

changeset 39: 86ce16b512b7
parent: 891ace7526cc
child: 14878efc5a61
author: Richard Westhaver <ellis@rwest.io>
date: Wed, 05 Jun 2024 17:00:54 -0400
permissions: -rw-r--r--
description: templates
1 ;;; ellis.el --- Richard's custom-file -*- lexical-binding: t; -*-
2 
3 ;; Copyright (C) 2023
4 
5 ;; Author: Richard Westhaver <ellis@rwest.io>
6 
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
11 
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16 
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
19 
20 ;;; Commentary:
21 
22 ;; This is an example of what you may want to add to your custom
23 ;; config file. Feel free to rip.
24 
25 ;;; Code:
26 (require 'inbox)
27 (require 'sk)
28 ;; (require 'slime-cape)
29 (require 'sxp)
30 (require 'ulang)
31 
32 (defalias 'make #'compile)
33 
34 (setopt default-theme 'modus-vivendi-tritanopia
35  user-lab-directory (join-paths user-home-directory "lab")
36  company-source-directory (join-paths user-home-directory "comp"))
37 
38 (unless (display-graphic-p) (setq default-theme 'wheatgrass))
39 
40 (when (linux-p) (setq dired-listing-switches "-alsh"))
41 
42 (defvar emacs-config-source (join-paths company-source-directory "core/emacs"))
43 
44 ;;;###autoload
45 (defun edit-emacs-config (&optional src)
46  (interactive (list current-prefix-arg))
47  (let ((file (if src
48  (expand-file-name "default.el" emacs-config-source)
49  user-custom-file)))
50  (find-file file)))
51 
52 (keymap-set user-map "e c" #'edit-emacs-config)
53 (keymap-set emacs-lisp-mode-map "C-c C-l" #'load-file)
54 (keymap-set emacs-lisp-mode-map "C-c M-k" #'elisp-byte-compile-file)
55 (keymap-set user-map "v t" #'org-tags-view)
56 
57 (require 'paredit)
58 (add-hook 'lisp-mode-hook #'enable-paredit-mode)
59 (add-hook 'slime-editing-mode-hook #'enable-paredit-mode)
60 (repeat-mode)
61 
62 (defun remember-project ()
63  (interactive)
64  (project-remember-project (project-current))
65  project--list)
66 
67 (defun remember-lab-projects ()
68  (interactive)
69  (project-remember-projects-under user-lab-directory t))
70 
71 (defun remember-comp-projects ()
72  (interactive)
73  (project-remember-projects-under company-source-directory t))
74 
75 (keymap-global-set "C-<tab>" #'hippie-expand)
76 (keymap-set minibuffer-local-map "C-<tab>" #'hippie-expand)
77 (keymap-set ctl-x-x-map "p p" #'remember-project)
78 (keymap-set ctl-x-x-map "p l" #'remember-lab-projects)
79 
80 (add-hook 'prog-mode-hook #'skel-minor-mode)
81 (add-hook 'org-mode-hook #'skel-minor-mode)
82 (add-hook 'prog-mode-hook #'company-mode)
83 
84 (add-hook 'notmuch-message-mode-hook #'turn-on-orgtbl)
85 
86 (use-package markdown-mode :ensure t)
87 
88 (use-package ol-notmuch :ensure t)
89 
90 (use-package notmuch
91  :ensure t
92  :init
93  (setopt
94  mail-user-agent 'message-user-agent
95  smtpmail-smtp-server "smtp.gmail.com"
96  message-send-mail-function 'message-smtpmail-send-it
97  smtpmail-debug-info t
98  message-default-mail-headers "Cc: \nBcc: \n"
99  message-kill-buffer-on-exit t
100  user-mail-address "richard.westhaver@gmail.com"
101  user-full-name "Richard Westhaver"
102  notmuch-hello-sections '(notmuch-hello-insert-saved-searches
103  notmuch-hello-insert-search
104  notmuch-hello-insert-recent-searches
105  notmuch-hello-insert-alltags)
106  notmuch-show-logo nil
107  notmuch-search-oldest-first nil
108  notmuch-hello-hide-tags '("kill")
109  notmuch-saved-searches '((:name "inbox" :query "tag:inbox" :key "i")
110  (:name "unread" :query "tag:unread" :key "u")
111  (:name "new" :query "tag:new" :key "n")
112  (:name "sent" :query "tag:sent" :key "e")
113  (:name "drafts" :query "tag:draft" :key "d")
114  (:name "all mail" :query "*" :key "a")
115  (:name "todo" :query "tag:todo" :key "t")))
116  :config
117  ;;;###autoload
118  (defun notmuch-exec-offlineimap ()
119  "execute offlineimap command and tag new mail with notmuch"
120  (interactive)
121  (start-process-shell-command "offlineimap"
122  "*offlineimap*"
123  "offlineimap -o")
124  (notmuch-refresh-all-buffers))
125 
126  (defun offlineimap-get-password (host port)
127  (let* ((netrc (netrc-parse (expand-file-name "~/.netrc.gpg")))
128  (hostentry (netrc-machine netrc host port port)))
129  (when hostentry (netrc-get hostentry "password"))))
130 
131  (defun mark-as-read ()
132  "mark message as read."
133  (interactive)
134  (notmuch-search-tag '("-new" "-unread" "-inbox")))
135 
136  (defun mark-as-todo ()
137  "mark message as todo."
138  (interactive)
139  (mark-as-read)
140  (notmuch-search-tag '("-new" "-unread" "-inbox" "+todo")))
141 
142  (defun mark-as-spam ()
143  "mark message as spam."
144  (interactive)
145  (mark-as-read)
146  (notmuch-search-tag (list "+spam")))
147 
148  (keymap-set user-map "e m" #'notmuch)
149  (keymap-set user-map "e M" #'notmuch-exec-offlineimap)
150  (keymap-set notmuch-search-mode-map "S" #'mark-as-spam)
151  (keymap-set notmuch-search-mode-map "R" #'mark-as-read)
152  (keymap-set notmuch-search-mode-map "T" #'mark-as-todo))
153 
154 (use-package elfeed
155  :ensure t
156  :custom
157  elfeed-feeds
158  '(("http://threesixty360.wordpress.com/feed/" blog math)
159  ("http://www.50ply.com/atom.xml" blog dev)
160  ("http://blog.cryptographyengineering.com/feeds/posts/default" blog)
161  ("http://abstrusegoose.com/feed.xml" comic)
162  ("http://accidental-art.tumblr.com/rss" image math)
163  ("http://researchcenter.paloaltonetworks.com/unit42/feed/" security)
164  ("http://curiousprogrammer.wordpress.com/feed/" blog dev)
165  ("http://feeds.feedburner.com/amazingsuperpowers" comic)
166  ("http://amitp.blogspot.com/feeds/posts/default" blog dev)
167  ("http://pages.cs.wisc.edu/~psilord/blog/rssfeed.rss" blog)
168  ("http://www.anticscomic.com/?feed=rss2" comic)
169  ("http://feeds.feedburner.com/blogspot/TPQSS" blog dev)
170  ("http://techchrunch.com/feeds" tech news)
171  ("https://rss.nytimes.com/services/xml/rss/nyt/Technology.xml" tech news)
172  ("https://static.fsf.org/fsforg/rss/news.xml" tech news)
173  ("https://feeds.npr.org/1001/rss.xml" news)
174  ("https://search.cnbc.com/rs/search/combinedcms/view.xml?partnerId=wrss01&id=10000664" fin news)
175  ("https://search.cnbc.com/rs/search/combinedcms/view.xml?partnerId=wrss01&id=19854910" tech news)
176  ("https://search.cnbc.com/rs/search/combinedcms/view.xml?partnerId=wrss01&id=100003114" us news)
177  ("http://arxiv.org/rss/cs" cs rnd)
178  ("http://arxiv.org/rss/math" math rnd)
179  ("http://arxiv.org/rss/q-fin" q-fin rnd)
180  ("http://arxiv.org/rss/stat" stat rnd)
181  ("http://arxiv.org/rss/econ" econ rnd)
182  ;; John Wiegley
183  ("http://newartisans.com/rss.xml" dev blog)
184  ;; comp
185  ;; ("https://lab.rwest.io/comp.atom?feed_token=pHu9qwLkjy4CWJHx9rrJ" comp vc)
186  ("https://www.reddit.com/r/listentothis/.rss" music reddit)
187  ("https://www.ftc.gov/feeds/press-release-consumer-protection.xml" gov ftc)
188  ("https://api2.fcc.gov/edocs/public/api/v1/rss/" gov fcc)
189  )
190  :init
191  (defun yt-dl-it (url)
192  "Downloads the URL in an async shell"
193  (let ((default-directory "~/media/yt"))
194  (async-shell-command (format "youtube-dl %s" url))))
195 
196  (defun elfeed-youtube-dl (&optional use-generic-p)
197  "Youtube-DL link"
198  (interactive "P")
199  (let ((entries (elfeed-search-selected)))
200  (cl-loop for entry in entries
201  do (elfeed-untag entry 'unread)
202  when (elfeed-entry-link entry)
203  do (yt-dl-it it))
204  (mapc #'elfeed-search-update-entry entries)
205  (unless (use-region-p) (forward-line))))
206  :config
207  (keymap-set elfeed-search-mode-map "d" 'elfeed-youtube-dl)
208  (keymap-set user-map "e f" #'elfeed)
209  (keymap-set user-map "e F" #'elfeed-update))
210 
211 (use-package org-mime :ensure t)
212 
213 (use-package sh-script
214  :hook (sh-mode . flymake-mode))
215 
216 ;;; Org Config
217 (keymap-set user-map "t" #'org-todo)
218 
219 ;; populate org-babel
220 (org-babel-do-load-languages
221  ;; TODO 2021-10-24: bqn, apl, k
222  'org-babel-load-languages '((shell . t)
223  (emacs-lisp . t)
224  (lisp . t)
225  (org . t)
226  (eshell . t)
227  (calc . t)
228  (sed . t)
229  (awk . t)
230  (dot . t)
231  (js . t)
232  (C . t)
233  (python . t)
234  (lua . t)
235  (lilypond . t)))
236 ;;; IRC
237 (setq erc-format-nick-function 'erc-format-@nick)
238 
239 (defun start-erc ()
240  "Connect to IRC."
241  (interactive)
242  (erc-tls :server "irc.libera.chat" :port 6697
243  :client-certificate '("/mnt/y/data/private/krypt/libera.pem"))
244  (setq erc-autojoin-channels-alist '(("irc.libera.chat" "#emacs")
245  ("irc.libera.chat" "#linux")
246  ("irc.libera.chat" "#rust")
247  ("irc.libera.chat" "#btrfs")
248  ("irc.libera.chat" "#lisp")
249  ("irc.libera.chat" "#sbcl")
250  ("irc.oftc.net" "#llvm"))))
251 ;;; Tags
252 ;;;###autoload
253 (defun refresh-tags ()
254  "Refresh TAGS database in `user-emacs-directory'."
255  (interactive)
256  (let ((default-directory user-emacs-directory))
257  (async-shell-command
258  "etags ./*.el \\
259 ./lib/*.el \\
260 ~/comp/org/*.el \\
261 ~/comp/core/emacs/*.el \\
262 ~/comp/core/emacs/lib/*.el \\
263 -o TAGS")))
264 
265 (unless (string-equal "hyde" system-name)
266  (add-hook 'dired-mode-hook #'all-the-icons-dired-mode)
267  (add-hook 'ibuffer-mode-hook #'all-the-icons-ibuffer-mode))
268 
269 ;; strangerdanger
270 ;; (setq slime-enable-evaluate-in-emacs t)
271 
272 (defun org-word-count (beg end
273  &optional count-latex-macro-args?
274  count-footnotes?)
275  "Report the number of words in the Org mode buffer or selected region.
276 Ignores:
277 - comments
278 - tables
279 - source code blocks (#+BEGIN_SRC ... #+END_SRC, and inline blocks)
280 - hyperlinks (but does count words in hyperlink descriptions)
281 - tags, priorities, and TODO keywords in headers
282 - sections tagged as 'not for export'.
283 
284 The text of footnote definitions is ignored, unless the optional argument
285 COUNT-FOOTNOTES? is non-nil.
286 
287 If the optional argument COUNT-LATEX-MACRO-ARGS? is non-nil, the word count
288 includes LaTeX macro arguments (the material between {curly braces}).
289 Otherwise, and by default, every LaTeX macro counts as 1 word regardless
290 of its arguments."
291  (interactive "r")
292  (unless mark-active
293  (setf beg (point-min)
294  end (point-max)))
295  (let ((wc 0)
296  (latex-macro-regexp "\\\\[A-Za-z]+\\(\\[[^]]*\\]\\|\\){\\([^}]*\\)}"))
297  (save-excursion
298  (goto-char beg)
299  (while (< (point) end)
300  (cond
301  ;; Ignore comments.
302  ((or (org-in-commented-line) (org-at-table-p))
303  nil)
304  ;; Ignore hyperlinks. But if link has a description, count
305  ;; the words within the description.
306  ((looking-at org-bracket-link-analytic-regexp)
307  (when (match-string-no-properties 5)
308  (let ((desc (match-string-no-properties 5)))
309  (save-match-data
310  (cl-incf wc (length (remove "" (org-split-string
311  desc "\\W")))))))
312  (goto-char (match-end 0)))
313  ((looking-at org-any-link-re)
314  (goto-char (match-end 0)))
315  ;; Ignore source code blocks.
316  ((org-in-regexps-block-p "^#\\+BEGIN_SRC\\W" "^#\\+END_SRC\\W")
317  nil)
318  ;; Ignore inline source blocks, counting them as 1 word.
319  ((save-excursion
320  (backward-char)
321  (looking-at org-babel-inline-src-block-regexp))
322  (goto-char (match-end 0))
323  (setf wc (+ 2 wc)))
324  ;; Count latex macros as 1 word, ignoring their arguments.
325  ((save-excursion
326  (backward-char)
327  (looking-at latex-macro-regexp))
328  (goto-char (if count-latex-macro-args?
329  (match-beginning 2)
330  (match-end 0)))
331  (setf wc (+ 2 wc)))
332  ;; Ignore footnotes.
333  ((and (not count-footnotes?)
334  (or (org-footnote-at-definition-p)
335  (org-footnote-at-reference-p)))
336  nil)
337  (t
338  (let ((contexts (org-context)))
339  (cond
340  ;; Ignore tags and TODO keywords, etc.
341  ((or (assoc :todo-keyword contexts)
342  (assoc :priority contexts)
343  (assoc :keyword contexts)
344  (assoc :checkbox contexts))
345  nil)
346  ;; Ignore sections marked with tags that are
347  ;; excluded from export.
348  ((assoc :tags contexts)
349  (if (intersection (org-get-tags-at) org-export-exclude-tags
350  :test 'equal)
351  (org-forward-same-level 1)
352  nil))
353  (t
354  (cl-incf wc))))))
355  (re-search-forward "\\w+\\W*")))
356  (message (format "%d words in %s." wc
357  (if mark-active "region" "buffer")))))
358 
359 (defun org-check-misformatted-subtree ()
360  "Check misformatted entries in the current buffer."
361  (interactive)
362  (show-all)
363  (org-map-entries
364  (lambda ()
365  (when (and (move-beginning-of-line 2)
366  (not (looking-at org-heading-regexp)))
367  (if (or (and (org-get-scheduled-time (point))
368  (not (looking-at (concat "^.*" org-scheduled-regexp))))
369  (and (org-get-deadline-time (point))
370  (not (looking-at (concat "^.*" org-deadline-regexp)))))
371  (when (y-or-n-p "Fix this subtree? ")
372  (message "Call the function again when you're done fixing this subtree.")
373  (recursive-edit))
374  (message "All subtrees checked."))))))
375 
376 (defun org-sort-list-by-checkbox-type ()
377  "Sort list items according to Checkbox state."
378  (interactive)
379  (org-sort-list
380  nil ?f
381  (lambda ()
382  (if (looking-at org-list-full-item-re)
383  (cdr (assoc (match-string 3)
384  '(("[X]" . 1) ("[-]" . 2) ("[ ]" . 3) (nil . 4))))
385  4))))
386 
387 (defun org-time-string-to-seconds (s)
388  "Convert a string HH:MM:SS to a number of seconds."
389  (cond
390  ((and (stringp s)
391  (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s))
392  (let ((hour (string-to-number (match-string 1 s)))
393  (min (string-to-number (match-string 2 s)))
394  (sec (string-to-number (match-string 3 s))))
395  (+ (* hour 3600) (* min 60) sec)))
396  ((and (stringp s)
397  (string-match "\\([0-9]+\\):\\([0-9]+\\)" s))
398  (let ((min (string-to-number (match-string 1 s)))
399  (sec (string-to-number (match-string 2 s))))
400  (+ (* min 60) sec)))
401  ((stringp s) (string-to-number s))
402  (t s)))
403 
404 (defun org-time-seconds-to-string (secs)
405  "Convert a number of seconds to a time string."
406  (cond ((>= secs 3600) (format-seconds "%h:%.2m:%.2s" secs))
407  ((>= secs 60) (format-seconds "%m:%.2s" secs))
408  (t (format-seconds "%s" secs))))
409 
410 (defmacro with-time (time-output-p &rest exprs)
411  "Evaluate an org-table formula, converting all fields that look
412 like time data to integer seconds. If TIME-OUTPUT-P then return
413 the result as a time value."
414  (list
415  (if time-output-p 'org-time-seconds-to-string 'identity)
416  (cons 'progn
417  (mapcar
418  (lambda (expr)
419  `,(cons (car expr)
420  (mapcar
421  (lambda (el)
422  (if (listp el)
423  (list 'with-time nil el)
424  (org-time-string-to-seconds el)))
425  (cdr expr))))
426  `,@exprs))))
427 
428 (defun org-hex-strip-lead (str)
429  (if (and (> (length str) 2) (string= (substring str 0 2) "0x"))
430  (substring str 2) str))
431 
432 (defun org-hex-to-hex (int)
433  (format "0x%x" int))
434 
435 (defun org-hex-to-dec (str)
436  (cond
437  ((and (stringp str)
438  (string-match "\\([0-9a-f]+\\)" (setf str (org-hex-strip-lead str))))
439  (let ((out 0))
440  (mapc
441  (lambda (ch)
442  (setf out (+ (* out 16)
443  (if (and (>= ch 48) (<= ch 57)) (- ch 48) (- ch 87)))))
444  (coerce (match-string 1 str) 'list))
445  out))
446  ((stringp str) (string-to-number str))
447  (t str)))
448 
449 (defmacro with-hex (hex-output-p &rest exprs)
450  "Evaluate an org-table formula, converting all fields that look
451  like hexadecimal to decimal integers. If HEX-OUTPUT-P then
452  return the result as a hex value."
453  (list
454  (if hex-output-p 'org-hex-to-hex 'identity)
455  (cons 'progn
456  (mapcar
457  (lambda (expr)
458  `,(cons (car expr)
459  (mapcar (lambda (el)
460  (if (listp el)
461  (list 'with-hex nil el)
462  (org-hex-to-dec el)))
463  (cdr expr))))
464  `,@exprs))))
465 
466 (require 'mm-url) ; to include mm-url-decode-entities-string
467 
468 (defun org-insert-link-with-title ()
469  "Insert org link where default description is set to html title."
470  (interactive)
471  (let* ((url (read-string "URL: "))
472  (title (get-html-title-from-url url)))
473  (org-insert-link nil url title)))
474 
475 (defun get-html-title-from-url (url)
476  "Return content in <title> tag."
477  (let (x1 x2 (download-buffer (url-retrieve-synchronously url)))
478  (save-excursion
479  (set-buffer download-buffer)
480  (beginning-of-buffer)
481  (setq x1 (search-forward "<title>"))
482  (search-forward "</title>")
483  (setq x2 (search-backward "<"))
484  (mm-url-decode-entities-string (buffer-substring-no-properties x1 x2)))))
485 
486 (defun org-remove-empty-propert-drawers ()
487  "*Remove all empty property drawers in current file."
488  (interactive)
489  (unless (eq major-mode 'org-mode)
490  (error "You need to turn on Org mode for this function."))
491  (save-excursion
492  (goto-char (point-min))
493  (while (re-search-forward ":PROPERTIES:" nil t)
494  (save-excursion
495  (org-remove-empty-drawer-at "PROPERTIES" (match-beginning 0))))))
496 
497 (defun check-for-clock-out-note ()
498  (interactive)
499  (save-excursion
500  (org-back-to-heading)
501  (let ((tags (org-get-tags)))
502  (and tags (message "tags: %s " tags)
503  (when (member "clocknote" tags)
504  (org-add-note))))))
505 
506 (add-hook 'org-clock-out-hook 'check-for-clock-out-note)
507 
508 (defun org-list-files (dirs ext)
509  "Function to create list of org files in multiple subdirectories.
510 This can be called to generate a list of files for
511 org-agenda-files or org-refile-targets.
512 
513 DIRS is a list of directories.
514 
515 EXT is a list of the extensions of files to be included."
516  (let ((dirs (if (listp dirs)
517  dirs
518  (list dirs)))
519  (ext (if (listp ext)
520  ext
521  (list ext)))
522  files)
523  (mapc
524  (lambda (x)
525  (mapc
526  (lambda (y)
527  (setq files
528  (append files
529  (file-expand-wildcards
530  (concat (file-name-as-directory x) "*" y)))))
531  ext))
532  dirs)
533  (mapc
534  (lambda (x)
535  (when (or (string-match "/.#" x)
536  (string-match "#$" x))
537  (setq files (delete x files))))
538  files)
539  files))
540 
541 (defvar org-agenda-directories (list org-directory user-lab-directory)
542  "List of directories containing org files.")
543 (defvar org-agenda-extensions '(".org")
544  "List of extensions of agenda files")
545 
546 (defun org-set-agenda-files ()
547  (interactive)
548  (setq org-agenda-files (org-list-files
549  org-agenda-directories
550  org-agenda-extensions)))
551 
552 (add-hook 'after-init-hook 'org-set-agenda-files)
553 
554 ;;; Skel Config
555 (use-package skel
556  :defer t
557  :load-path user-emacs-lib-directory
558  :config
559  (setq
560  tempo-interactive t
561  auto-insert 'no-modify
562  auto-insert-query nil
563  skt-enable-tempo-elements t
564  skt-delete-duplicate-marks t)
565 
566  (defvar skt-default-version "0.1.0")
567 
568  (keymap-set skt-minor-mode-map "b" #'tempo-backward-mark)
569  (keymap-set skt-minor-mode-map "f" #'tempo-forward-mark)
570  (keymap-set skt-minor-mode-map "SPC" #'tempo-complete-tag)
571  (keymap-set skt-minor-mode-map "t" #'skt-add-tag)
572 
573  (defvar skt-skeleton-path-function #'abbreviate-file-name
574  "Function to be called when expanding file-header skeletons. Useful to
575 rebind locally inside a project or module, where you want to delete some
576 prefix or replace it.")
577 
578  (defun skt-buffer-path (&optional function)
579  (let ((path (or buffer-file-name (format "%s.lisp" (gensym "scratch-")))))
580  (funcall (or function skt-skeleton-path-function) path)))
581 
582  (defun skt-skelfile-path ()
583  (if (string= (file-name-nondirectory buffer-file-name) "skelfile")
584  "skelfile"
585  (skt-buffer-path)))
586 
587  ;; functions
588  (skt-define-function capture (:abbrev "capture" :tag t) org-capture)
589  (skt-define-function agenda (:abbrev "agenda" :tag t) org-agenda)
590  (skt-define-function mjump (:abbrev "mjump" :tag t) bookmark-jump)
591  (skt-define-function bjump (:abbrev "bjump" :tag t) ibuffer-jump)
592  (skt-define-function rjump (:abbrev "rjump" :tag t)
593  (lambda () (jump-to-register (read-char "register: "))))
594  (skt-define-function pjump (:abbrev "pjump" :tag t) (lambda () (project-switch-project default-directory)))
595 
596  ;; templates
597  (skt-define-template readme (:mode org-mode :tag t)
598  "#+title: " (p "title: ") n
599  "#+description: " (p "description: ") n
600  "#+author: " user-full-name n
601  "#+email:" user-mail-address n
602  "#+setupfile: clean.theme" n
603  "#+export_file_name: index" n>
604  p n> n>
605  ":info:" n>
606  "+ version :: " skt-default-version n
607  ":end:" n>)
608 
609  ;; TODO 2024-06-04:
610  ;; (skt-define-template defsystem (:mode lisp-mode :tag t :abbrev "defsystem"))
611  ;; (skt-define-template defpackage (:mode lisp-mode :tag t :abbrev "defpackage"))
612  ;; (skt-define-template defpkg (:mode lisp-mode :tag t :abbrev "defpkg"))
613 
614  (skt-define-template defmacro (:abbrev "(defmacro" :tag t :mode lisp-mode)
615  "(defmacro " (p "Name: ") " (" (p "Args: ") ")" > n> r ")")
616 
617  (skt-define-template defun (:abbrev "(defun" :tag t :mode lisp-mode)
618  "(defun " (p "Name: ") " (" (p "Args: ") ")" > n> r ")")
619 
620  (skt-define-template defvar (:abbrev "(defvar" :tag t :mode lisp-mode)
621  > "(defvar " > r ")")
622 
623  ;; skeletons
624  (skt-define-skeleton head (:abbrev "head" :mode lisp-mode)
625  "description: "
626  ";;; " (skt-buffer-path 'file-name-nondirectory) " --- " str \n \n ";; " _ \n \n ";;; Code:" \n >)
627 
628  (skt-define-skeleton head (:abbrev "head" :mode skel-mode)
629  "description: "
630  ";;; " (skt-skelfile-path) " --- " str " -*- mode: skel; -*-" \n _)
631 
632  (skt-define-skeleton head (:abbrev "head" :mode org-mode)
633  "title: "
634  "#+title: " str \n
635  "#+author: " (skeleton-read "author: ") \n
636  "#+description: " (skeleton-read "description: ") \n
637  "#+setupfile: clean.theme" \n > _)
638 
639  (skt-define-skeleton head (:abbrev "head" :mode rust-mode)
640  "description: "
641  "//! " (skt-buffer-path 'file-name-nondirectory) " --- " str \n \n "// " _ \n \n "//! Code: " \n >)
642 
643  (skt-define-skeleton system-head (:abbrev "system-head" :mode lisp-mode)
644  "system-name: "
645  ";;; " (skt-buffer-path) " --- "
646  '(setq v1 (file-name-base (skt-buffer-path))) (capitalize v1)
647  " Sytem Definitions" \n
648  > "(defsystem :" v1 \n
649  > ":depends-on (:std :log)" \n
650  > ":components ((:file \"pkg\")" _ "))")
651 
652  (skt-define-skeleton crate-head (:abbrev "crate-head" :mode conf-toml-mode)
653  "ignored"
654  "### " (skt-buffer-path 'file-name-nondirectory) " --- "
655  '(setq v1 (skeleton-read "name: ")) v1 " Cargo Manifest" \n >
656  "[package]" \n
657  "name = \"" v1 "\"" \n
658  "version = \"" skt-default-version "\"" \n
659  "[dependencies]" \n >)
660 
661  (skt-define-skeleton local-vars
662  (:tag t :abbrev "local-vars"
663  :docstring "Insert a local variables section. Use current comment syntax if any.")
664  (completing-read "Mode: " obarray
665  (lambda (symbol)
666  (if (commandp symbol)
667  (string-match "-mode$" (symbol-name symbol))))
668  t)
669  '(save-excursion
670  (if (re-search-forward page-delimiter nil t)
671  (error "Not on last page")))
672  comment-start "Local Variables:" comment-end \n
673  comment-start "mode: " str
674  & -5 | '(kill-line 0) & -1 | comment-end \n
675  ( (completing-read (format "Variable, %s: " skeleton-subprompt)
676  obarray
677  (lambda (symbol)
678  (or (eq symbol 'eval)
679  (custom-variable-p symbol)))
680  t)
681  comment-start str ": "
682  (read-from-minibuffer "Expression: " nil read-expression-map nil
683  'read-expression-history) | _
684  comment-end \n)
685  resume:
686  comment-start "End:" comment-end \n)
687 
688  ;; autoinsert
689  (skt-register-auto-insert "skelfile" #'skt-template-skel-head)
690  (skt-register-auto-insert "readme.org" #'skt-template-org-readme)
691  (skt-register-auto-insert "Cargo.toml" #'skt-template-conf-toml-crate-head)
692  (skt-register-auto-insert ".*[.]asd" #'skt-template-lisp-system-head)
693  (skt-register-auto-insert ".*[.]lisp" #'skt-template-lisp-head)
694  (skt-register-auto-insert ".*[.].rs" #'skt-template-rust-head)
695  (auto-insert-mode t)
696  (keymap-set skel-minor-mode-map "C-<return>" 'company-tempo))
697 
698 (provide 'ellis)
699 ;;; ellis.el ends here