changeset 36: |
963513ec0fcd |
parent: |
6eef2d50b7fd
|
child: |
964e4427f5ad |
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Tue, 04 Jun 2024 18:54:01 -0400 |
permissions: |
-rw-r--r-- |
description: |
skt-templates |
1 ;;; ellis.el --- Richard's custom-file -*- lexical-binding: t; -*- 5 ;; Author: Richard Westhaver <ellis@rwest.io> 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. 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. 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/>. 22 ;; This is an example of what you may want to add to your custom 23 ;; config file. Feel free to rip. 28 ;; (require 'slime-cape) 32 (defalias 'make #'compile) 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")) 38 (unless (display-graphic-p) (setq default-theme 'wheatgrass)) 40 (when (linux-p) (setq dired-listing-switches "-alsh")) 42 (defvar emacs-config-source (join-paths company-source-directory "core/emacs")) 45 (defun edit-emacs-config (&optional src) 46 (interactive (list current-prefix-arg)) 48 (expand-file-name "default.el" emacs-config-source) 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) 58 (add-hook 'lisp-mode-hook #'enable-paredit-mode) 59 (add-hook 'slime-editing-mode-hook #'enable-paredit-mode) 62 (defun remember-project () 64 (project-remember-project (project-current)) 67 (defun remember-lab-projects () 69 (project-remember-projects-under user-lab-directory t)) 71 (defun remember-comp-projects () 73 (project-remember-projects-under company-source-directory t)) 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) 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) 84 (add-hook 'notmuch-message-mode-hook #'turn-on-orgtbl) 86 (use-package markdown-mode :ensure t) 88 (use-package ol-notmuch :ensure t) 94 mail-user-agent 'message-user-agent 95 smtpmail-smtp-server "smtp.gmail.com" 96 message-send-mail-function 'message-smtpmail-send-it 98 message-default-mail-headers "Cc: \nBcc: \n" 99 message-kill-buffer-on-exit t 100 user-mail-address "ellis@rwest.io" 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"))) 118 (defun notmuch-exec-offlineimap () 119 "execute offlineimap command and tag new mail with notmuch" 121 (start-process-shell-command "offlineimap" 124 (notmuch-refresh-all-buffers)) 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")))) 131 (defun mark-as-read () 132 "mark message as read." 134 (notmuch-search-tag '("-new" "-unread" "-inbox"))) 136 (defun mark-as-todo () 137 "mark message as todo." 140 (notmuch-search-tag '("-new" "-unread" "-inbox" "+todo"))) 142 (defun mark-as-spam () 143 "mark message as spam." 146 (notmuch-search-tag (list "+spam"))) 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)) 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) 183 ("http://newartisans.com/rss.xml" dev blog) 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) 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)))) 196 (defun elfeed-youtube-dl (&optional use-generic-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) 204 (mapc #'elfeed-search-update-entry entries) 205 (unless (use-region-p) (forward-line)))) 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)) 211 (use-package org-mime :ensure t) 213 (use-package sh-script 214 :hook (sh-mode . flymake-mode)) 220 (tempo-define-template 223 "#+AUTHOR: " user-full-name " <" user-mail-address ">" n>) 225 "Insert a readme.org file template.") 226 (tempo-define-template "org:src" 227 '("#+begin_src " p n> 231 (keymap-set user-map "t" #'org-todo) 233 ;; populate org-babel 234 (org-babel-do-load-languages 235 ;; TODO 2021-10-24: bqn, apl, k 236 'org-babel-load-languages '((shell . t) 251 (setq erc-format-nick-function 'erc-format-@nick) 256 (erc-tls :server "irc.libera.chat" :port 6697 257 :client-certificate '("/mnt/y/data/private/krypt/libera.pem")) 258 (setq erc-autojoin-channels-alist '(("irc.libera.chat" "#emacs") 259 ("irc.libera.chat" "#linux") 260 ("irc.libera.chat" "#rust") 261 ("irc.libera.chat" "#btrfs") 262 ("irc.libera.chat" "#lisp") 263 ("irc.libera.chat" "#sbcl") 264 ("irc.oftc.net" "#llvm")))) 267 (defun refresh-tags () 268 "Refresh TAGS database in `user-emacs-directory'." 270 (let ((default-directory user-emacs-directory)) 275 ~/comp/core/emacs/*.el \\ 276 ~/comp/core/emacs/lib/*.el \\ 279 (unless (string-equal "hyde" system-name) 280 (add-hook 'dired-mode-hook #'all-the-icons-dired-mode) 281 (add-hook 'ibuffer-mode-hook #'all-the-icons-ibuffer-mode)) 284 (setq slime-enable-evaluate-in-emacs t) 286 (defun org-word-count (beg end 287 &optional count-latex-macro-args? 289 "Report the number of words in the Org mode buffer or selected region. 293 - source code blocks (#+BEGIN_SRC ... #+END_SRC, and inline blocks) 294 - hyperlinks (but does count words in hyperlink descriptions) 295 - tags, priorities, and TODO keywords in headers 296 - sections tagged as 'not for export'. 298 The text of footnote definitions is ignored, unless the optional argument 299 COUNT-FOOTNOTES? is non-nil. 301 If the optional argument COUNT-LATEX-MACRO-ARGS? is non-nil, the word count 302 includes LaTeX macro arguments (the material between {curly braces}). 303 Otherwise, and by default, every LaTeX macro counts as 1 word regardless 307 (setf beg (point-min) 310 (latex-macro-regexp "\\\\[A-Za-z]+\\(\\[[^]]*\\]\\|\\){\\([^}]*\\)}")) 313 (while (< (point) end) 316 ((or (org-in-commented-line) (org-at-table-p)) 318 ;; Ignore hyperlinks. But if link has a description, count 319 ;; the words within the description. 320 ((looking-at org-bracket-link-analytic-regexp) 321 (when (match-string-no-properties 5) 322 (let ((desc (match-string-no-properties 5))) 324 (cl-incf wc (length (remove "" (org-split-string 326 (goto-char (match-end 0))) 327 ((looking-at org-any-link-re) 328 (goto-char (match-end 0))) 329 ;; Ignore source code blocks. 330 ((org-in-regexps-block-p "^#\\+BEGIN_SRC\\W" "^#\\+END_SRC\\W") 332 ;; Ignore inline source blocks, counting them as 1 word. 335 (looking-at org-babel-inline-src-block-regexp)) 336 (goto-char (match-end 0)) 338 ;; Count latex macros as 1 word, ignoring their arguments. 341 (looking-at latex-macro-regexp)) 342 (goto-char (if count-latex-macro-args? 347 ((and (not count-footnotes?) 348 (or (org-footnote-at-definition-p) 349 (org-footnote-at-reference-p))) 352 (let ((contexts (org-context))) 354 ;; Ignore tags and TODO keywords, etc. 355 ((or (assoc :todo-keyword contexts) 356 (assoc :priority contexts) 357 (assoc :keyword contexts) 358 (assoc :checkbox contexts)) 360 ;; Ignore sections marked with tags that are 361 ;; excluded from export. 362 ((assoc :tags contexts) 363 (if (intersection (org-get-tags-at) org-export-exclude-tags 365 (org-forward-same-level 1) 369 (re-search-forward "\\w+\\W*"))) 370 (message (format "%d words in %s." wc 371 (if mark-active "region" "buffer"))))) 373 (defun org-check-misformatted-subtree () 374 "Check misformatted entries in the current buffer." 379 (when (and (move-beginning-of-line 2) 380 (not (looking-at org-heading-regexp))) 381 (if (or (and (org-get-scheduled-time (point)) 382 (not (looking-at (concat "^.*" org-scheduled-regexp)))) 383 (and (org-get-deadline-time (point)) 384 (not (looking-at (concat "^.*" org-deadline-regexp))))) 385 (when (y-or-n-p "Fix this subtree? ") 386 (message "Call the function again when you're done fixing this subtree.") 388 (message "All subtrees checked.")))))) 390 (defun org-sort-list-by-checkbox-type () 391 "Sort list items according to Checkbox state." 396 (if (looking-at org-list-full-item-re) 397 (cdr (assoc (match-string 3) 398 '(("[X]" . 1) ("[-]" . 2) ("[ ]" . 3) (nil . 4)))) 401 (defun org-time-string-to-seconds (s) 402 "Convert a string HH:MM:SS to a number of seconds." 405 (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s)) 406 (let ((hour (string-to-number (match-string 1 s))) 407 (min (string-to-number (match-string 2 s))) 408 (sec (string-to-number (match-string 3 s)))) 409 (+ (* hour 3600) (* min 60) sec))) 411 (string-match "\\([0-9]+\\):\\([0-9]+\\)" s)) 412 (let ((min (string-to-number (match-string 1 s))) 413 (sec (string-to-number (match-string 2 s)))) 415 ((stringp s) (string-to-number s)) 418 (defun org-time-seconds-to-string (secs) 419 "Convert a number of seconds to a time string." 420 (cond ((>= secs 3600) (format-seconds "%h:%.2m:%.2s" secs)) 421 ((>= secs 60) (format-seconds "%m:%.2s" secs)) 422 (t (format-seconds "%s" secs)))) 424 (defmacro with-time (time-output-p &rest exprs) 425 "Evaluate an org-table formula, converting all fields that look 426 like time data to integer seconds. If TIME-OUTPUT-P then return 427 the result as a time value." 429 (if time-output-p 'org-time-seconds-to-string 'identity) 437 (list 'with-time nil el) 438 (org-time-string-to-seconds el))) 442 (defun org-hex-strip-lead (str) 443 (if (and (> (length str) 2) (string= (substring str 0 2) "0x")) 444 (substring str 2) str)) 446 (defun org-hex-to-hex (int) 449 (defun org-hex-to-dec (str) 452 (string-match "\\([0-9a-f]+\\)" (setf str (org-hex-strip-lead str)))) 456 (setf out (+ (* out 16) 457 (if (and (>= ch 48) (<= ch 57)) (- ch 48) (- ch 87))))) 458 (coerce (match-string 1 str) 'list)) 460 ((stringp str) (string-to-number str)) 463 (defmacro with-hex (hex-output-p &rest exprs) 464 "Evaluate an org-table formula, converting all fields that look 465 like hexadecimal to decimal integers. If HEX-OUTPUT-P then 466 return the result as a hex value." 468 (if hex-output-p 'org-hex-to-hex 'identity) 475 (list 'with-hex nil el) 476 (org-hex-to-dec el))) 480 (require 'mm-url) ; to include mm-url-decode-entities-string 482 (defun org-insert-link-with-title () 483 "Insert org link where default description is set to html title." 485 (let* ((url (read-string "URL: ")) 486 (title (get-html-title-from-url url))) 487 (org-insert-link nil url title))) 489 (defun get-html-title-from-url (url) 490 "Return content in <title> tag." 491 (let (x1 x2 (download-buffer (url-retrieve-synchronously url))) 493 (set-buffer download-buffer) 494 (beginning-of-buffer) 495 (setq x1 (search-forward "<title>")) 496 (search-forward "</title>") 497 (setq x2 (search-backward "<")) 498 (mm-url-decode-entities-string (buffer-substring-no-properties x1 x2))))) 500 (defun org-remove-empty-propert-drawers () 501 "*Remove all empty property drawers in current file." 503 (unless (eq major-mode 'org-mode) 504 (error "You need to turn on Org mode for this function.")) 506 (goto-char (point-min)) 507 (while (re-search-forward ":PROPERTIES:" nil t) 509 (org-remove-empty-drawer-at "PROPERTIES" (match-beginning 0)))))) 511 (defun check-for-clock-out-note () 514 (org-back-to-heading) 515 (let ((tags (org-get-tags))) 516 (and tags (message "tags: %s " tags) 517 (when (member "clocknote" tags) 520 (add-hook 'org-clock-out-hook 'check-for-clock-out-note) 522 (defun org-list-files (dirs ext) 523 "Function to create list of org files in multiple subdirectories. 524 This can be called to generate a list of files for 525 org-agenda-files or org-refile-targets. 527 DIRS is a list of directories. 529 EXT is a list of the extensions of files to be included." 530 (let ((dirs (if (listp dirs) 543 (file-expand-wildcards 544 (concat (file-name-as-directory x) "*" y))))) 549 (when (or (string-match "/.#" x) 550 (string-match "#$" x)) 551 (setq files (delete x files)))) 555 (defvar org-agenda-directories (list org-directory user-lab-directory) 556 "List of directories containing org files.") 557 (defvar org-agenda-extensions '(".org") 558 "List of extensions of agenda files") 560 (defun org-set-agenda-files () 562 (setq org-agenda-files (org-list-files 563 org-agenda-directories 564 org-agenda-extensions))) 566 (add-hook 'after-init-hook 'org-set-agenda-files) 570 (setopt skt-enable-tempo-elements t 571 skt-delete-duplicate-marks t) 573 (keymap-set skt-minor-mode-map "b" #'tempo-backward-mark) 574 (keymap-set skt-minor-mode-map "f" #'tempo-forward-mark) 575 (keymap-set skt-minor-mode-map "SPC" #'tempo-complete-tag) 576 (keymap-set skt-minor-mode-map "t" #'skt-add-tag) 578 (skt-define-template defmacro (:abbrev "defvar" :tag t :mode lisp-mode) 579 "(defmacro " (p "Name: ") " (" (p "Args: ") ")" > n> r ")") 581 (skt-define-template defun (:abbrev "defvar" :tag t :mode lisp-mode) 582 "(defun " (p "Name: ") " (" (p "Args: ") ")" > n> r ")") 584 (skt-define-template defvar (:abbrev "defvar" :tag t :mode lisp-mode) 585 > "(defvar " > r ")") 587 (skt-define-function capture (:abbrev "capture" :tag t) org-capture) 588 (skt-define-function agenda (:abbrev "agenda" :tag t) org-agenda) 589 (skt-define-function mjump (:abbrev "mjump" :tag t) bookmark-jump) 590 (skt-define-function bjump (:abbrev "bjump" :tag t) ibuffer-jump) 591 (skt-define-function rjump (:abbrev "rjump" :tag t) 592 (lambda () (jump-to-register (read-char "register: ")))) 593 (skt-define-function pjump (:abbrev "pjump" :tag t) (lambda () (project-switch-project default-directory))) 595 (defvar skt-skeleton-path-function #'abbreviate-file-name 596 "Function to be called when expanding file-header skeletons. Useful to 597 rebind locally inside a project or module, where you want to delete some 598 prefix or replace it.") 600 (defun skt-buffer-path () (funcall skt-skeleton-path-function buffer-file-name)) 602 (defun skt-skelfile-path () 603 (if (string= (file-name-nondirectory buffer-file-name) "skelfile") 607 (skt-define-skeleton head (:abbrev "head" :mode lisp-mode) 609 ";;; " (skt-buffer-path) " --- " str \n \n \n ";;; Code:" \n > _) 611 (skt-define-skeleton head (:abbrev "head" :mode rust-mode) 613 "//! " (skt-buffer-path) " --- " str \n \n "// " _ \n \n "//! Code:" \n > _) 615 (skt-define-skeleton head (:abbrev "head" :mode skel-mode) 617 ";;; " (skt-skelfile-path) " --- " str " -*- mode: skel; -*-" \n _) 619 (skt-define-skeleton head (:abbrev "head" :mode org-mode) 622 "#+author: " (skeleton-read "author: ") \n 623 "#+description: " (skeleton-read "description: ") \n 624 "#+setupfile: clean.theme" \n > _) 626 (skt-define-skeleton local-vars 627 (:tag t :abbrev "local-vars" 628 :docstring "Insert a local variables section. Use current comment syntax if any.") 629 (completing-read "Mode: " obarray 631 (if (commandp symbol) 632 (string-match "-mode$" (symbol-name symbol)))) 635 (if (re-search-forward page-delimiter nil t) 636 (error "Not on last page"))) 637 comment-start "Local Variables:" comment-end \n 638 comment-start "mode: " str 639 & -5 | '(kill-line 0) & -1 | comment-end \n 640 ( (completing-read (format "Variable, %s: " skeleton-subprompt) 643 (or (eq symbol 'eval) 644 (custom-variable-p symbol))) 646 comment-start str ": " 647 (read-from-minibuffer "Expression: " nil read-expression-map nil 648 'read-expression-history) | _ 651 comment-start "End:" comment-end \n) 654 (skt-register-auto-insert "skelfile" #'skt-template-skel-head) 655 (setq auto-insert :unmodified) 656 (setq auto-insert-query nil) 659 (keymap-set skel-minor-mode-map "C-<return>" 'company-tempo) 662 ;;; ellis.el ends here