+++ /dev/null
-;;; re-howm.el -*- lexical-binding: t; -*-
-;; This file is not part of GNU Emacs
-
-;;; Code:
-
-(setq howm-template-list '("= %title%cursor #inbox\n%date %file\n\n"
- "= %title%cursor #meeting\n%date %file\n\nAttendees: \n"
- "= @%title%cursor\n%date %file\n\n")
- howm-template howm-template-list
- howm-keyword-file "~/howm/.howm-keys"
- howm-history-file "~/howm/.howm-history"
- howm-menu-file "~/.emacs.d/0000-00-00-000000.txt"
- howm-file-name-format "%Y%m%dT%H%M%S.txt"
- howm-keyword-case-fold-search t
- howm-remember-insertion-format "%s"
- howm-menu-todo-num 10)
-
-(defun re/howm-menu-new-frame (&optional arg)
- "Show the howm menu in a new frame"
- (interactive "P")
- (re/open-with-new-frame "HOWM" #'howm-menu))
-
-(defun re/howm-create-keyword ()
- "Reads a keyword from the minibuffer and appends it to the keywords file."
- (interactive)
- (append-to-file (concat (read-string "New Keyword: ")
- "\n")
- nil
- howm-keyword-file))
-\f
-;; Menu tweaks
-
-;; add entries in howm-menu (press enter on the text)
-(dolist (aldr-additions '(("\\[Mtg\\]"
- (lambda (&optional dummy)
- (howm-create 2)))
- ("\\[Person\\]"
- (lambda (&optional dummy)
- (howm-create 3)))))
- (add-to-list 'action-lock-default-rules
- aldr-additions
- t))
-
-(defun re/howm-menu-legend ()
- (cl-labels ((p (text face) (propertize text 'font-lock-face face)))
- (concat (format "Top %s" howm-menu-todo-num)
- " "
- (p "!Deadline" howm-reminder-deadline-face)
- "/"
- (p "+ToDo" howm-reminder-todo-face)
- "/"
- (p "@Schedule" howm-reminder-schedule-face)
- "/"
- (p "~Defer" howm-reminder-defer-face)
- "/"
- (p "-Reminder" howm-reminder-normal-face)
- " Entries:")))
-
-(add-to-list 'howm-menu-allow 're/howm-menu-legend)
-
-;; add coloring for custom "waiting" state
-(add-to-list 'howm-reminder-font-lock-keywords
- `(,(howm-reminder-regexp "[w]")
- (0 howm-reminder-defer-face prepend))
- t)
-
-(dolist (hooks '(after-save-hook howm-mode-hook))
- (add-hook hooks 'howm-mode-set-buffer-name))
-
-(provide 're-howm)
-;;; re-howm.el ends here
+++ /dev/null
-;;; re-mu4e.el --- Setup mu4e --- -*- lexical-binding: t; -*-
-;; This file is not part of GNU Emacs
-
-;;; Code:
-
-(use-package mu4e
- :ensure nil
- :config
- (setq mu4e-get-mail-command "mbsync -a"
- mu4e-update-interval (* 10 60)
- mu4e-change-filenames-when-moving t
- mu4e-use-fancy-chars t
- mu4e-attachment-dir "~/downloads"
- mu4e-compose-reply-to-address "iv@earman.xyz"
- mu4e-maildir "~/mail"
- mu4e-drafts-folder "/iv/Drafts"
- mu4e-sent-folder "/iv/Sent"
- mu4e-trash-folder "/iv/Trash"
- mu4e-maildir-shortcuts '((:maildir "/iv/inbox" :key ?i)
- (:maildir "/iv/Sent" :key ?s)
- (:maildir "/iv/Trash" :key ?t)
- (:maildir "/iv/Drafts" :key ?d))))
-
-(setq mail-user-agent 'message-user-agent
- message-send-mail-function 'smtpmail-send-it
- message-citation-line-format "Quoth %f :\n"
- smtpmail-default-smtp-server "mail.earman.xyz"
- smtpmail-smtp-server "mail.earman.xyz"
- smtpmail-smtp-service 587
- smtpmail-stream-type 'starttls
- smtpmail-local-domain "earman.xyz"
- smtpmail-queue-mail nil
- smtpmail-queue-dir "~/mail/iv/outbox/cur")
-
-(setq user-mail-address "iv@earman.xyz"
- user-full-name "Rush N. Earman IV"
- message-signature "Rush Earman IV, PE"
- message-kill-buffer-on-exit t)
-
-(provide 're-mu4e)
-;;; re-mu4e.el ends here
+++ /dev/null
-;;; re-org.el --- org-mode bespokeniŋ -*- lexical-binding: t; -*-
-;; This file is not part of GNU Emacs
-
-;;; Code:
-
-;; General options
-(add-to-list 'org-export-backends 'md)
-
-(setq org-startup-indented t
- org-startup-folded 'fold
- org-startup-with-inline-images t
- org-cycle-inline-images-display t
- org-cycle-separator-lines 0
- org-blank-before-new-entry '((heading) (plain-list-item . auto))
- org-M-RET-may-split-line nil
- org-treat-S-cursor-todo-selection-as-state-change nil
- org-treat-insert-todo-heading-as-state-change nil
- org-table-export-default-format "orgtbl-to-csv"
- org-list-allow-alphabetical t
- org-fold-catch-invisible-edits 'show-and-error
- org-ellipsis " ↴"
- org-tags-column 0
- org-enforce-todo-dependencies t
- org-enforce-todo-checkbox-dependencies t
- org-fontify-done-headline nil
- org-fontify-todo-headline nil
- org-goto-interface 'outline-path-completion
- org-outline-path-complete-in-steps nil
- org-goto-auto-isearch nil
- org-special-ctrl-a/e t
- org-special-ctrl-k t
- org-return-follows-link t
- org-yank-adjusted-subtrees t
- org-todo-keyword-faces '(("WAITING" :foreground "#e15400" :weight bold)
- ("UNDERTAKEN" :foreground "magenta" :weight bold)
- ("MEETING" :foreground "#315e9a" :weight bold)))
-
-(add-hook 'org-agenda-mode-hook #'hl-line-mode)
-
-\f
-;; Time Clocking
-(org-clock-persistence-insinuate)
-(setq org-clock-history-length 10
- org-clock-in-resume t
- org-clock-out-remove-zero-time-clocks t
- org-clock-persist t
- org-clock-persist-query-resume nil
- org-clock-report-include-clocking-task t
- org-time-stamp-rounding-minutes '(1 1))
-
-\f
-;; Agenda and capture
-(setq org-agenda-files (append '("~/org/")
- (file-expand-wildcards "~/projects/*/"))
- org-refile-targets '((nil :maxlevel . 9)
- (org-agenda-files :maxlevel . 9))
- org-refile-use-outline-path 'file
- org-refile-allow-creating-parent-nodes 'confirm
- org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d)" "BELAYED(b@)" "GIVEN(g@)")
- (sequence "MEETING(m)" "|" "MET(M)"))
- org-tag-alist '(("call" . ?c)
- ("email" . ?e)
- ("errand" . ?r)
- ("jobpc" . ?j)
- ("license" . ?l)
- ("open" . ?o))
- org-tags-exclude-from-inheritance '("open")
- org-agenda-restore-windows-after-quit t
- org-agenda-start-on-weekday nil
- org-agenda-compact-blocks t
- org-agenda-span 'day
- org-deadline-warning-days 30
- org-agenda-window-setup 'current-window
- org-agenda-time-grid '((daily today remove-match)
- (600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900)
- " ――――― "
- "")
- org-agenda-tags-column 0
- org-agenda-remove-tags t
- org-agenda-skip-additional-timestamps-same-entry t
- org-agenda-skip-deadline-if-done t
- org-agenda-skip-scheduled-if-done t
- org-agenda-prefix-format '((agenda . "%25c:%?-12t% s")
- (todo . "%25c:%?-12t% s")
- (tags . "%25c:%?-12t% s")
- (search . "%25c:%?-12t% s"))
- org-agenda-scheduled-leaders '("BOOKED: " "Booked %2d d. ago: ")
- org-agenda-deadline-leaders '("DEADLINE: " "In %3d d.: " "%2d d. ago: ")
- org-read-date-prefer-future 'time
- org-agenda-custom-commands
- '(("d" "Done items" todo "DONE|BELAYED|GIVEN|MET" ((org-agenda-skip-function
- '(org-agenda-skip-entry-if 'notregexp "^\\*\\* "))
- (org-agenda-overriding-header "DONE - MAYBE KEEP:")))
- ("f" "Maybe Someday" tags "someday" ((org-agenda-skip-function
- '(org-agenda-skip-entry-if 'regexp "^\\* someday"))
- (org-agenda-overriding-header "SOMEDAY:")))
- ("i" "Inbox" tags "inbox" ((org-agenda-skip-function
- '(org-agenda-skip-entry-if 'regexp "^\\* inbox"))
- (org-agenda-overriding-header "INBOX:")))
- ("l" "Licenses" tags "license" ((org-agenda-overriding-header "LICENSES:")))
- ("n" "Next Actions" tags-todo "-recurring/TODO" ((org-agenda-overriding-header "NEXT:")
- (org-agenda-sorting-strategy
- '((agenda tag-up time-up)))))
- ("p" "JobPCs" tags "jobpc" ((org-agenda-overriding-header "JOB PCS:")))
- ("u" "Undertakings" tags "open" ((org-agenda-overriding-header "UNDERTAKINGS:")))
- ("w" "Waiting" todo "WAITING" ((org-agenda-overriding-header "WAITING:")))
- ("o" "Overview" ((agenda "")
- (tags "inbox" ((org-agenda-overriding-header "\nINBOX:")))
- (tags "open" ((org-agenda-skip-function
- '(org-agenda-skip-entry-if 'notregexp "^\\* "))
- (org-agenda-overriding-header "\nUNDERTAKINGS:")))
- (todo "WAITING" ((org-agenda-overriding-header "\nWAITING:"))))))
- org-agenda-start-with-log-mode t
- org-agenda-log-mode-items '(closed clock state)
- org-log-done 'time
- org-log-into-drawer t
- org-capture-templates '(("i" "Inbox" entry
- (file "inbox.org")
- "* %^{Description}\n%U\n%?"
- :clock-in t
- :clock-resume t)
- ("m" "Meeting" entry
- (file "inbox.org")
- "* %^{Description}\n%^{Scheduled:}T\n%?"
- :clock-in t
- :clock-resume t)
- ("p" "Phone Call" entry
- (file "inbox.org")
- "* %^{Description} :call:\n%U\n%?"
- :clock-in t
- :clock-resume t))
- org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
- org-id-method 'ts
- org-clone-delete-id t
- org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
- org-attach-id-uuid-folder-format))
-
-(defun re/org-auto-generate-ids-in-file ()
- "Add ID properties to all headlines in the current
- file which do not already have one."
- (interactive)
- (org-map-entries 'org-id-get-create))
-
-(defun re/org-save-all ()
- "Save all `org-agenda-files' without user confirmation."
- (interactive)
- (message "Saving all org-agenda-files buffers...")
- (save-some-buffers t
- (lambda ()
- (when (member (buffer-file-name) org-agenda-files) t)))
- (message "Saving all org-agenda-files buffers... done"))
-
-(advice-add 'org-refile :after (lambda (&rest _) (re/org-save-all)))
-\f
-;; Archiving (use re/org-archive-all periodically)
-(defun re/org-archive-all ()
- "Archive all tasks marked `DONE' in agenda files"
- (interactive)
- (message "Archiving all completed tasks in org-agenda-files...")
- (org-map-entries (lambda ()
- (org-archive-subtree)
- (setq org-map-continue-from (org-element-property
- :begin
- (org-element-at-point))))
- "/DONE"
- 'agenda)
- (message "Archiving all completed tasks in org-agenda-files... done"))
-
-(setq org-archive-location (concat "~/org/old.org_keep::datetree/")
- org-agenda-text-search-extra-files '(agenda-archives))
-
-(add-to-list 'auto-mode-alist '("\\.org_keep\\'" . org-mode))
-
-(provide 're-org)
-;;; re-org.el ends here
+++ /dev/null
-;;; re-packages.el --- Load Packs -*- lexical-binding: t; -*-
-;; This file is not part of Emacs.
-
-;;; Code:
-
-(require 'package)
-
-(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
-
-(setq use-package-always-ensure t
- use-package-always-demand t)
-\f
-;; UI/Editing
-
-(use-package corfu
- :custom
- (corfu-auto t)
- (corfu-auto-delay 0)
- (corfu-auto-prefix 1)
- :config
- (global-corfu-mode))
-
-(use-package corfu-popupinfo
- :ensure
- nil ; part of corfu
- :after
- corfu
- :hook
- (corfu-mode . corfu-popupinfo-mode)
- :custom
- (corfu-popupinfo-delay '(nil . 0.01)) ; start with M-t, fast refresh once on
- (corfu-popupinfo-hide nil)
- :config
- (corfu-popupinfo-mode))
-
-(use-package expand-region
- :bind
- (("C-=" . er/expand-region)))
-
-(use-package aggressive-indent)
-
-(use-package magit
- :defer
- t
- :config
- (message "Magit Loaded"))
-
-(use-package page-break-lines
- :config
- (global-page-break-lines-mode))
-\f
-;; Filetypes
-(use-package auctex
- :config
- (setq TeX-auto-save t
- TeX-parse-self t
- TeX-PDF-mode t)
- (setq-default TeX-master nil))
-
-(use-package csv-mode
- :config
- (add-hook 'csv-mode-hook 'csv-align-mode))
-
-(use-package markdown-mode
- :config
- (setq markdown-special-ctrl-a/e t)
- :bind
- (:map markdown-mode-map
- ("M-<right>" . markdown-demote)
- ("M-<left>" . markdown-promote)
- ("M-<up>" . markdown-move-up)
- ("M-<down>" . markdown-move-down)
- ("C-M-u" . markdown-up-heading)
- ("C-M-b" . markdown-outline-previous-same-level)
- ("C-M-f" . markdown-outline-next-same-level)
- ("C-M-p" . markdown-outline-previous)
- ("C-M-n" . markdown-outline-next)))
-
-(use-package edit-indirect :after 'markdown-mode)
-\f
-;; REPLs
-(use-package sly
- :config
- (setq inferior-lisp-program "sbcl"
- sly-net-coding-system 'utf-8-unix
- sly-command-switch-to-existing-lisp 'always)
- (let ((core (expand-file-name "~/sbcl.core-for-sly")))
- (when (file-exists-p core)
- (setq sly-lisp-implementations (list `(sbcl ("sbcl" "--core" ,core)))))))
-
-(use-package geiser
- :config
- (if (equal system-type 'windows-nt)
- (setq geiser-chicken-binary '("C:/tools/chicken/bin/csi.exe" "-:c"))
- (setq geiser-chicken-binary "csi -:c"))
- (setq scheme-program-name geiser-chicken-binary
- geiser-active-implementations '(chicken))
- (add-hook 'scheme-mode-hook 'geiser-mode))
-
-(use-package geiser-chicken :after 'geiser)
-
-(use-package forth-mode)
-\f
-;; PIM
-(use-package org
- :config
- (require 're-org)
- :bind
- (("C-c l" . org-store-link)
- ("C-c a" . org-agenda)
- ("C-c c" . org-capture)
- ("C-c b" . org-switchb)
- ("<f10>" . org-clock-out)
- ("<f2>" . org-clock-goto)
- :map org-mode-map
- ("M-<right>" . org-shiftmetaright)
- ("M-<left>" . org-shiftmetaleft)
- ("M-S-<right>" . org-metaright)
- ("M-S-<left>" . org-metaleft)
- ("C-M-h" . org-mark-subtree)
- ("C-M-u" . org-up-element)
- ("C-M-d" . org-down-element)
- ("C-M-b" . org-backward-heading-same-level)
- ("C-M-f" . org-forward-heading-same-level)
- ("C-M-p" . org-previous-visible-heading)
- ("C-M-n" . org-next-visible-heading)
- ("<f9>" . org-clock-in)))
-
-(use-package org-transclusion
- :after
- org
- :bind
- (("C-c t" . org-transclusion-mode)))
-
-(with-eval-after-load 'org-transclusion
- (add-to-list 'org-transclusion-extensions 'org-transclusion-indent-mode)
- (require 'org-transclusion-indent-mode))
-
-(use-package howm
- :config
- (require 're-howm)
- :bind
- (("<f6>" . howm-menu)
- ("S-<f6>" . re/howm-menu-new-frame)
- :map howm-mode-map
- ("C-c , k" . re/howm-create-keyword)
- ("C-c , =" . howm-narrow-to-memo)))
-\f
-;; MISC
-(use-package trashed
- :config
- (setq trashed-action-confirmer 'y-or-n-p
- trashed-use-header-line t
- trashed-sort-key '("Date deleted" . t)
- trashed-date-format "%Y-%m-%d %H:%M:%S"))
-
-(provide 're-packages)
-;;; re-packages.el ends here
+++ /dev/null
-;;; re-pass-alike.el -*- lexical-binding: t; -*-
-;; This file is not part of GNU Emacs.
-
-;;; Code:
-
-;; Generate totp code
-(dolist (requirement '(bindat gnutls hexl auth-source))
- (require requirement))
-
-(defun totp--hex-decode-string (string)
- "Hex-decode STRING and return the result as a unibyte string."
- (apply #'unibyte-string
- (seq-map (lambda (s) (hexl-htoi (aref s 0) (aref s 1)))
- (seq-partition string 2))))
-
-(defun totp (string &optional time digits)
- "Return a TOTP token using the secret hex STRING and current time.
-TIME is used as counter value instead of current time, if non-nil.
-DIGITS is the number of pin digits and defaults to 6."
- (let* ((key-bytes (totp--hex-decode-string (upcase string)))
- (counter (truncate (/ (or time (time-to-seconds)) 30)))
- (digits (or digits 6))
- (format-string (format "%%0%dd" digits))
- ;; we have to manually split the 64 bit number (u64 not supported in Emacs 27.2)
- (counter-bytes (bindat-pack '((:high u32) (:low u32))
- `((:high . ,(ash counter -32)) (:low . ,(logand counter #xffffffff)))))
- (mac (gnutls-hash-mac 'SHA1 key-bytes counter-bytes))
- (offset (logand (bindat-get-field (bindat-unpack '((:offset u8)) mac 19) :offset) #xf)))
- (format format-string
- (mod
- (logand (bindat-get-field (bindat-unpack '((:totp-pin u32)) mac offset) :totp-pin)
- #x7fffffff)
- (expt 10 digits)))))
-
-(defconst base32-alphabet
- (let ((tbl (make-char-table nil)))
- (dolist (mapping '(("A" . 0) ("B" . 1) ("C" . 2) ("D" . 3)
- ("E" . 4) ("F" . 5) ("G" . 6)
- ("H" . 7) ("I" . 8) ("J" . 9) ("K" . 10)
- ("L" . 11) ("M" . 12) ("N" . 13)
- ("O" . 14) ("P" . 15) ("Q" . 16) ("R" . 17)
- ("S" . 18) ("T" . 19) ("U" . 20)
- ("V" . 21) ("W" . 22) ("X" . 23) ("Y" . 24)
- ("Z" . 25) ("2" . 26) ("3" . 27)
- ("4" . 28) ("5" . 29) ("6" . 30) ("7" . 31)))
- (aset tbl (string-to-char (car mapping)) (cdr mapping)))
- tbl)
- "Base-32 mapping table, as defined in RFC 4648.")
-
-(defun base32-hex-decode (string)
- "The cheats' version of base-32 decode.
-
-This is not a 100% faithful implementation of RFC 4648. The
-concept of encoding partial quanta is not implemented fully.
-
-No attempt is made to pad the output either as that is not
-required for HMAC-TOTP."
- (unless (mod (length string) 8)
- (error "Padding is incorrect"))
- (setq string (upcase string))
- (let ((trimmed-array (append (string-trim-right string "=+") nil)))
- (format "%X" (seq-reduce
- (lambda (acc char) (+ (ash acc 5) (aref base32-alphabet char)))
- trimmed-array 0))))
-
-(defun keyfile-string (filename)
- "Return a string which is the filepath to a `pass(1)' file."
- (let ((directory "~/.password-store/"))
- (if (null filename)
- (read-file-name "Select a password: " directory nil t nil)
- (concat directory
- (if (stringp filename)
- filename
- (symbol-name filename))
- ".gpg"))))
-
-(defun get-totp (&optional filename)
- "Generate a totp code given a file with the secret hex string.
-If no filename given, prompt for one.
-Assumes the file has the string by itself on the last line of the file,
-similar to what pass-otp does, but without the full uri.
-Also assumes the file is in `~/.password-store' and has the `.gpg' extension."
- (totp (base32-hex-decode (re/get-line-from-file (keyfile-string filename) -1))))
-
-(defun otp-to-clipboard (&optional filename)
- "Copy the returned totp code to the clipboard."
- (interactive)
- (kill-new (get-totp filename)))
-\f
-;; Find password from pass(1) entry
-
-(defun get-password (&optional filename)
- "Return a password given a file where it is stored.
-Assumes same structure as `pass(1)'."
- (re/get-line-from-file (keyfile-string filename) 1))
-
-(defun password-to-clipboard (&optional filename)
- "Copy the returned password to the clipboard."
- (interactive)
- (kill-new (get-password filename)))
-\f
-;; Password generation
-
-(defconst *alphanumerics*
- '("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"
- "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
- "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
- "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
- "0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
- "List of strings of the upper/lower-case English alphabet, and the single-digit numbers.")
-
-(defconst *special-characters*
- '("!" "?" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "."
- "/" ":" ";" "<" "=" ">" "?" "@" "[" "]" "^" "_" "{"
- "|" "}" "~")
- "List of strings containing the special visible characters excluding \\ and \" .")
-
-(defun pw-get-char (&optional no-special-chars)
- "Select a single character at random to be used in a password.
-If `no-special-chars' is t, use only alpha-numeric characters."
- (let ((selected-charset (append *alphanumerics*
- (when (null no-special-chars)
- *special-characters*))))
- (elt selected-charset (random (length selected-charset)))))
-
-(defun pw-get-chars (password-length &optional no-special-chars)
- "Generate a list of characters as strings to be made into a password.
-If `no-special-chars' is t, use only alpha-numeric characters."
- (append (list (pw-get-char no-special-chars))
- (when (> password-length 1)
- (pw-get-chars (- password-length 1) no-special-chars))))
-
-(defun generate-password (password-length &optional no-special-chars)
- "Combine a list of randomly-selected characters into a single string of length given.
-calls `pw-get-chars'. If `no-special-chars' is `t', use only alpha-numeric characters."
- (apply #'concat (pw-get-chars password-length no-special-chars)))
-
-(defun insert-generated-password (&optional password-length)
- "Insert a generated password into the current buffer.
-Negative password-length (or negative arg) sets `no-special-chars' for `generate-password'."
- (interactive "p")
- (let ((len (if (or (null password-length) (= 1 (abs password-length)))
- 16
- (abs password-length)))
- (no-special-p (and (numberp password-length) (< password-length 0))))
- (insert (generate-password len no-special-p))))
-
-(provide 're-pass-alike)
-;;; re-pass-alike.el ends here
--- /dev/null
+;;; re-howm.el -*- lexical-binding: t; -*-
+;; This file is not part of GNU Emacs
+
+;;; Code:
+
+(setq howm-template-list '("= %title%cursor #inbox\n%date %file\n\n"
+ "= %title%cursor #meeting\n%date %file\n\nAttendees: \n"
+ "= @%title%cursor\n%date %file\n\n")
+ howm-template howm-template-list
+ howm-keyword-file "~/howm/.howm-keys"
+ howm-history-file "~/howm/.howm-history"
+ howm-menu-file "~/.emacs.d/0000-00-00-000000.txt"
+ howm-file-name-format "%Y%m%dT%H%M%S.txt"
+ howm-keyword-case-fold-search t
+ howm-remember-insertion-format "%s"
+ howm-menu-todo-num 10)
+
+(defun re/howm-menu-new-frame (&optional arg)
+ "Show the howm menu in a new frame"
+ (interactive "P")
+ (re/open-with-new-frame "HOWM" #'howm-menu))
+
+(defun re/howm-create-keyword ()
+ "Reads a keyword from the minibuffer and appends it to the keywords file."
+ (interactive)
+ (append-to-file (concat (read-string "New Keyword: ")
+ "\n")
+ nil
+ howm-keyword-file))
+\f
+;; Menu tweaks
+
+;; add entries in howm-menu (press enter on the text)
+(dolist (aldr-additions '(("\\[Mtg\\]"
+ (lambda (&optional dummy)
+ (howm-create 2)))
+ ("\\[Person\\]"
+ (lambda (&optional dummy)
+ (howm-create 3)))))
+ (add-to-list 'action-lock-default-rules
+ aldr-additions
+ t))
+
+(defun re/howm-menu-legend ()
+ (cl-labels ((p (text face) (propertize text 'font-lock-face face)))
+ (concat (format "Top %s" howm-menu-todo-num)
+ " "
+ (p "!Deadline" howm-reminder-deadline-face)
+ "/"
+ (p "+ToDo" howm-reminder-todo-face)
+ "/"
+ (p "@Schedule" howm-reminder-schedule-face)
+ "/"
+ (p "~Defer" howm-reminder-defer-face)
+ "/"
+ (p "-Reminder" howm-reminder-normal-face)
+ " Entries:")))
+
+(add-to-list 'howm-menu-allow 're/howm-menu-legend)
+
+;; add coloring for custom "waiting" state
+(add-to-list 'howm-reminder-font-lock-keywords
+ `(,(howm-reminder-regexp "[w]")
+ (0 howm-reminder-defer-face prepend))
+ t)
+
+(dolist (hooks '(after-save-hook howm-mode-hook))
+ (add-hook hooks 'howm-mode-set-buffer-name))
+
+(provide 're-howm)
+;;; re-howm.el ends here
--- /dev/null
+;;; re-mu4e.el --- Setup mu4e --- -*- lexical-binding: t; -*-
+;; This file is not part of GNU Emacs
+
+;;; Code:
+
+(use-package mu4e
+ :ensure nil
+ :config
+ (setq mu4e-get-mail-command "mbsync -a"
+ mu4e-update-interval (* 10 60)
+ mu4e-change-filenames-when-moving t
+ mu4e-use-fancy-chars t
+ mu4e-attachment-dir "~/downloads"
+ mu4e-compose-reply-to-address "iv@earman.xyz"
+ mu4e-maildir "~/mail"
+ mu4e-drafts-folder "/iv/Drafts"
+ mu4e-sent-folder "/iv/Sent"
+ mu4e-trash-folder "/iv/Trash"
+ mu4e-maildir-shortcuts '((:maildir "/iv/inbox" :key ?i)
+ (:maildir "/iv/Sent" :key ?s)
+ (:maildir "/iv/Trash" :key ?t)
+ (:maildir "/iv/Drafts" :key ?d))))
+
+(setq mail-user-agent 'message-user-agent
+ message-send-mail-function 'smtpmail-send-it
+ message-citation-line-format "Quoth %f :\n"
+ smtpmail-default-smtp-server "mail.earman.xyz"
+ smtpmail-smtp-server "mail.earman.xyz"
+ smtpmail-smtp-service 587
+ smtpmail-stream-type 'starttls
+ smtpmail-local-domain "earman.xyz"
+ smtpmail-queue-mail nil
+ smtpmail-queue-dir "~/mail/iv/outbox/cur")
+
+(setq user-mail-address "iv@earman.xyz"
+ user-full-name "Rush N. Earman IV"
+ message-signature "Rush Earman IV, PE"
+ message-kill-buffer-on-exit t)
+
+(provide 're-mu4e)
+;;; re-mu4e.el ends here
--- /dev/null
+;;; re-org.el --- org-mode bespokeniŋ -*- lexical-binding: t; -*-
+;; This file is not part of GNU Emacs
+
+;;; Code:
+
+;; General options
+(add-to-list 'org-export-backends 'md)
+
+(setq org-startup-indented t
+ org-startup-folded 'fold
+ org-startup-with-inline-images t
+ org-cycle-inline-images-display t
+ org-cycle-separator-lines 0
+ org-blank-before-new-entry '((heading) (plain-list-item . auto))
+ org-M-RET-may-split-line nil
+ org-treat-S-cursor-todo-selection-as-state-change nil
+ org-treat-insert-todo-heading-as-state-change nil
+ org-table-export-default-format "orgtbl-to-csv"
+ org-list-allow-alphabetical t
+ org-fold-catch-invisible-edits 'show-and-error
+ org-ellipsis " ↴"
+ org-tags-column 0
+ org-enforce-todo-dependencies t
+ org-enforce-todo-checkbox-dependencies t
+ org-fontify-done-headline nil
+ org-fontify-todo-headline nil
+ org-goto-interface 'outline-path-completion
+ org-outline-path-complete-in-steps nil
+ org-goto-auto-isearch nil
+ org-special-ctrl-a/e t
+ org-special-ctrl-k t
+ org-return-follows-link t
+ org-yank-adjusted-subtrees t
+ org-todo-keyword-faces '(("WAITING" :foreground "#e15400" :weight bold)
+ ("UNDERTAKEN" :foreground "magenta" :weight bold)
+ ("MEETING" :foreground "#315e9a" :weight bold)))
+
+(add-hook 'org-agenda-mode-hook #'hl-line-mode)
+
+\f
+;; Time Clocking
+(org-clock-persistence-insinuate)
+(setq org-clock-history-length 10
+ org-clock-in-resume t
+ org-clock-out-remove-zero-time-clocks t
+ org-clock-persist t
+ org-clock-persist-query-resume nil
+ org-clock-report-include-clocking-task t
+ org-time-stamp-rounding-minutes '(1 1))
+
+\f
+;; Agenda and capture
+(setq org-agenda-files (append '("~/org/")
+ (file-expand-wildcards "~/projects/*/"))
+ org-refile-targets '((nil :maxlevel . 9)
+ (org-agenda-files :maxlevel . 9))
+ org-refile-use-outline-path 'file
+ org-refile-allow-creating-parent-nodes 'confirm
+ org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d)" "BELAYED(b@)" "GIVEN(g@)")
+ (sequence "MEETING(m)" "|" "MET(M)"))
+ org-tag-alist '(("call" . ?c)
+ ("email" . ?e)
+ ("errand" . ?r)
+ ("jobpc" . ?j)
+ ("license" . ?l)
+ ("open" . ?o))
+ org-tags-exclude-from-inheritance '("open")
+ org-agenda-restore-windows-after-quit t
+ org-agenda-start-on-weekday nil
+ org-agenda-compact-blocks t
+ org-agenda-span 'day
+ org-deadline-warning-days 30
+ org-agenda-window-setup 'current-window
+ org-agenda-time-grid '((daily today remove-match)
+ (600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900)
+ " ――――― "
+ "")
+ org-agenda-tags-column 0
+ org-agenda-remove-tags t
+ org-agenda-skip-additional-timestamps-same-entry t
+ org-agenda-skip-deadline-if-done t
+ org-agenda-skip-scheduled-if-done t
+ org-agenda-prefix-format '((agenda . "%25c:%?-12t% s")
+ (todo . "%25c:%?-12t% s")
+ (tags . "%25c:%?-12t% s")
+ (search . "%25c:%?-12t% s"))
+ org-agenda-scheduled-leaders '("BOOKED: " "Booked %2d d. ago: ")
+ org-agenda-deadline-leaders '("DEADLINE: " "In %3d d.: " "%2d d. ago: ")
+ org-read-date-prefer-future 'time
+ org-agenda-custom-commands
+ '(("d" "Done items" todo "DONE|BELAYED|GIVEN|MET" ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'notregexp "^\\*\\* "))
+ (org-agenda-overriding-header "DONE - MAYBE KEEP:")))
+ ("f" "Maybe Someday" tags "someday" ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'regexp "^\\* someday"))
+ (org-agenda-overriding-header "SOMEDAY:")))
+ ("i" "Inbox" tags "inbox" ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'regexp "^\\* inbox"))
+ (org-agenda-overriding-header "INBOX:")))
+ ("l" "Licenses" tags "license" ((org-agenda-overriding-header "LICENSES:")))
+ ("n" "Next Actions" tags-todo "-recurring/TODO" ((org-agenda-overriding-header "NEXT:")
+ (org-agenda-sorting-strategy
+ '((agenda tag-up time-up)))))
+ ("p" "JobPCs" tags "jobpc" ((org-agenda-overriding-header "JOB PCS:")))
+ ("u" "Undertakings" tags "open" ((org-agenda-overriding-header "UNDERTAKINGS:")))
+ ("w" "Waiting" todo "WAITING" ((org-agenda-overriding-header "WAITING:")))
+ ("o" "Overview" ((agenda "")
+ (tags "inbox" ((org-agenda-overriding-header "\nINBOX:")))
+ (tags "open" ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'notregexp "^\\* "))
+ (org-agenda-overriding-header "\nUNDERTAKINGS:")))
+ (todo "WAITING" ((org-agenda-overriding-header "\nWAITING:"))))))
+ org-agenda-start-with-log-mode t
+ org-agenda-log-mode-items '(closed clock state)
+ org-log-done 'time
+ org-log-into-drawer t
+ org-capture-templates '(("i" "Inbox" entry
+ (file "inbox.org")
+ "* %^{Description}\n%U\n%?"
+ :clock-in t
+ :clock-resume t)
+ ("m" "Meeting" entry
+ (file "inbox.org")
+ "* %^{Description}\n%^{Scheduled:}T\n%?"
+ :clock-in t
+ :clock-resume t)
+ ("p" "Phone Call" entry
+ (file "inbox.org")
+ "* %^{Description} :call:\n%U\n%?"
+ :clock-in t
+ :clock-resume t))
+ org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
+ org-id-method 'ts
+ org-clone-delete-id t
+ org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
+ org-attach-id-uuid-folder-format))
+
+(defun re/org-auto-generate-ids-in-file ()
+ "Add ID properties to all headlines in the current
+ file which do not already have one."
+ (interactive)
+ (org-map-entries 'org-id-get-create))
+
+(defun re/org-save-all ()
+ "Save all `org-agenda-files' without user confirmation."
+ (interactive)
+ (message "Saving all org-agenda-files buffers...")
+ (save-some-buffers t
+ (lambda ()
+ (when (member (buffer-file-name) org-agenda-files) t)))
+ (message "Saving all org-agenda-files buffers... done"))
+
+(advice-add 'org-refile :after (lambda (&rest _) (re/org-save-all)))
+\f
+;; Archiving (use re/org-archive-all periodically)
+(defun re/org-archive-all ()
+ "Archive all tasks marked `DONE' in agenda files"
+ (interactive)
+ (message "Archiving all completed tasks in org-agenda-files...")
+ (org-map-entries (lambda ()
+ (org-archive-subtree)
+ (setq org-map-continue-from (org-element-property
+ :begin
+ (org-element-at-point))))
+ "/DONE"
+ 'agenda)
+ (message "Archiving all completed tasks in org-agenda-files... done"))
+
+(setq org-archive-location (concat "~/org/old.org_keep::datetree/")
+ org-agenda-text-search-extra-files '(agenda-archives))
+
+(add-to-list 'auto-mode-alist '("\\.org_keep\\'" . org-mode))
+
+(provide 're-org)
+;;; re-org.el ends here
--- /dev/null
+;;; re-packages.el --- Load Packs -*- lexical-binding: t; -*-
+;; This file is not part of Emacs.
+
+;;; Code:
+
+(require 'package)
+
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+
+(setq use-package-always-ensure t
+ use-package-always-defer t)
+\f
+;; UI/Editing
+
+(use-package corfu
+ :demand
+ t
+ :custom
+ (corfu-auto t)
+ (corfu-auto-delay 0)
+ (corfu-auto-prefix 1)
+ :config
+ (global-corfu-mode))
+
+(use-package corfu-popupinfo
+ :ensure
+ nil ; part of corfu
+ :after
+ corfu
+ :hook
+ (corfu-mode . corfu-popupinfo-mode)
+ :custom
+ (corfu-popupinfo-delay '(1.0 . 0.01)) ; start with M-t, fast refresh once on
+ (corfu-popupinfo-hide nil)
+ :config
+ (corfu-popupinfo-mode))
+
+(use-package expand-region
+ :bind
+ (("C-=" . er/expand-region)))
+
+(use-package aggressive-indent :defer t)
+
+(use-package magit
+ :config
+ (message "Magit Loaded"))
+
+(use-package page-break-lines
+ :demand
+ t
+ :config
+ (global-page-break-lines-mode))
+\f
+;; Filetypes
+(use-package auctex
+ :config
+ (setq TeX-auto-save t
+ TeX-parse-self t
+ TeX-PDF-mode t)
+ (setq-default TeX-master nil))
+
+(use-package csv-mode
+ :config
+ (add-hook 'csv-mode-hook 'csv-align-mode))
+
+(use-package markdown-mode
+ :config
+ (setq markdown-special-ctrl-a/e t)
+ :bind
+ (:map markdown-mode-map
+ ("M-<right>" . markdown-demote)
+ ("M-<left>" . markdown-promote)
+ ("M-<up>" . markdown-move-up)
+ ("M-<down>" . markdown-move-down)
+ ("C-M-u" . markdown-up-heading)
+ ("C-M-b" . markdown-outline-previous-same-level)
+ ("C-M-f" . markdown-outline-next-same-level)
+ ("C-M-p" . markdown-outline-previous)
+ ("C-M-n" . markdown-outline-next)))
+
+(use-package edit-indirect :after 'markdown-mode)
+\f
+;; REPLs
+(use-package sly
+ :config
+ (setq inferior-lisp-program "sbcl"
+ sly-net-coding-system 'utf-8-unix
+ sly-command-switch-to-existing-lisp 'always)
+ (let ((core (expand-file-name "~/sbcl.core-for-sly")))
+ (when (file-exists-p core)
+ (setq sly-lisp-implementations (list `(sbcl ("sbcl" "--core" ,core)))))))
+
+(use-package geiser
+ :config
+ (if (equal system-type 'windows-nt)
+ (setq geiser-chicken-binary '("C:/tools/chicken/bin/csi.exe" "-:c"))
+ (setq geiser-chicken-binary "csi -:c"))
+ (setq scheme-program-name geiser-chicken-binary
+ geiser-active-implementations '(chicken))
+ (add-hook 'scheme-mode-hook 'geiser-mode))
+
+(use-package geiser-chicken :after 'geiser)
+
+(use-package forth-mode)
+\f
+;; PIM
+(use-package org
+ :config
+ (require 're-org)
+ :bind
+ (("C-c l" . org-store-link)
+ ("C-c a" . org-agenda)
+ ("C-c c" . org-capture)
+ ("C-c b" . org-switchb)
+ ("<f10>" . org-clock-out)
+ ("<f2>" . org-clock-goto)
+ :map org-mode-map
+ ("M-<right>" . org-shiftmetaright)
+ ("M-<left>" . org-shiftmetaleft)
+ ("M-S-<right>" . org-metaright)
+ ("M-S-<left>" . org-metaleft)
+ ("C-M-h" . org-mark-subtree)
+ ("C-M-u" . org-up-element)
+ ("C-M-d" . org-down-element)
+ ("C-M-b" . org-backward-heading-same-level)
+ ("C-M-f" . org-forward-heading-same-level)
+ ("C-M-p" . org-previous-visible-heading)
+ ("C-M-n" . org-next-visible-heading)
+ ("<f9>" . org-clock-in)))
+
+(use-package org-transclusion
+ :after
+ org
+ :bind
+ (("C-c t" . org-transclusion-mode)))
+
+(use-package howm
+ :config
+ (require 're-howm)
+ :bind
+ (("<f6>" . howm-menu)
+ ("S-<f6>" . re/howm-menu-new-frame)
+ :map howm-mode-map
+ ("C-c , k" . re/howm-create-keyword)
+ ("C-c , =" . howm-narrow-to-memo)))
+\f
+;; MISC
+(use-package trashed
+ :config
+ (setq trashed-action-confirmer 'y-or-n-p
+ trashed-use-header-line t
+ trashed-sort-key '("Date deleted" . t)
+ trashed-date-format "%Y-%m-%d %H:%M:%S"))
+
+(provide 're-packages)
+;;; re-packages.el ends here
--- /dev/null
+;;; re-pass-alike.el -*- lexical-binding: t; -*-
+;; This file is not part of GNU Emacs.
+
+;;; Code:
+
+;; Generate totp code
+(dolist (requirement '(bindat gnutls hexl auth-source))
+ (require requirement))
+
+(defun totp--hex-decode-string (string)
+ "Hex-decode STRING and return the result as a unibyte string."
+ (apply #'unibyte-string
+ (seq-map (lambda (s) (hexl-htoi (aref s 0) (aref s 1)))
+ (seq-partition string 2))))
+
+(defun totp (string &optional time digits)
+ "Return a TOTP token using the secret hex STRING and current time.
+TIME is used as counter value instead of current time, if non-nil.
+DIGITS is the number of pin digits and defaults to 6."
+ (let* ((key-bytes (totp--hex-decode-string (upcase string)))
+ (counter (truncate (/ (or time (time-to-seconds)) 30)))
+ (digits (or digits 6))
+ (format-string (format "%%0%dd" digits))
+ ;; we have to manually split the 64 bit number (u64 not supported in Emacs 27.2)
+ (counter-bytes (bindat-pack '((:high u32) (:low u32))
+ `((:high . ,(ash counter -32)) (:low . ,(logand counter #xffffffff)))))
+ (mac (gnutls-hash-mac 'SHA1 key-bytes counter-bytes))
+ (offset (logand (bindat-get-field (bindat-unpack '((:offset u8)) mac 19) :offset) #xf)))
+ (format format-string
+ (mod
+ (logand (bindat-get-field (bindat-unpack '((:totp-pin u32)) mac offset) :totp-pin)
+ #x7fffffff)
+ (expt 10 digits)))))
+
+(defconst base32-alphabet
+ (let ((tbl (make-char-table nil)))
+ (dolist (mapping '(("A" . 0) ("B" . 1) ("C" . 2) ("D" . 3)
+ ("E" . 4) ("F" . 5) ("G" . 6)
+ ("H" . 7) ("I" . 8) ("J" . 9) ("K" . 10)
+ ("L" . 11) ("M" . 12) ("N" . 13)
+ ("O" . 14) ("P" . 15) ("Q" . 16) ("R" . 17)
+ ("S" . 18) ("T" . 19) ("U" . 20)
+ ("V" . 21) ("W" . 22) ("X" . 23) ("Y" . 24)
+ ("Z" . 25) ("2" . 26) ("3" . 27)
+ ("4" . 28) ("5" . 29) ("6" . 30) ("7" . 31)))
+ (aset tbl (string-to-char (car mapping)) (cdr mapping)))
+ tbl)
+ "Base-32 mapping table, as defined in RFC 4648.")
+
+(defun base32-hex-decode (string)
+ "The cheats' version of base-32 decode.
+
+This is not a 100% faithful implementation of RFC 4648. The
+concept of encoding partial quanta is not implemented fully.
+
+No attempt is made to pad the output either as that is not
+required for HMAC-TOTP."
+ (unless (mod (length string) 8)
+ (error "Padding is incorrect"))
+ (setq string (upcase string))
+ (let ((trimmed-array (append (string-trim-right string "=+") nil)))
+ (format "%X" (seq-reduce
+ (lambda (acc char) (+ (ash acc 5) (aref base32-alphabet char)))
+ trimmed-array 0))))
+
+(defun keyfile-string (filename)
+ "Return a string which is the filepath to a `pass(1)' file."
+ (let ((directory "~/.password-store/"))
+ (if (null filename)
+ (read-file-name "Select a password: " directory nil t nil)
+ (concat directory
+ (if (stringp filename)
+ filename
+ (symbol-name filename))
+ ".gpg"))))
+
+(defun get-totp (&optional filename)
+ "Generate a totp code given a file with the secret hex string.
+If no filename given, prompt for one.
+Assumes the file has the string by itself on the last line of the file,
+similar to what pass-otp does, but without the full uri.
+Also assumes the file is in `~/.password-store' and has the `.gpg' extension."
+ (totp (base32-hex-decode (re/get-line-from-file (keyfile-string filename) -1))))
+
+(defun otp-to-clipboard (&optional filename)
+ "Copy the returned totp code to the clipboard."
+ (interactive)
+ (kill-new (get-totp filename)))
+\f
+;; Find password from pass(1) entry
+
+(defun get-password (&optional filename)
+ "Return a password given a file where it is stored.
+Assumes same structure as `pass(1)'."
+ (re/get-line-from-file (keyfile-string filename) 1))
+
+(defun password-to-clipboard (&optional filename)
+ "Copy the returned password to the clipboard."
+ (interactive)
+ (kill-new (get-password filename)))
+\f
+;; Password generation
+
+(defconst *alphanumerics*
+ '("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"
+ "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
+ "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
+ "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
+ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
+ "List of strings of the upper/lower-case English alphabet, and the single-digit numbers.")
+
+(defconst *special-characters*
+ '("!" "?" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "."
+ "/" ":" ";" "<" "=" ">" "?" "@" "[" "]" "^" "_" "{"
+ "|" "}" "~")
+ "List of strings containing the special visible characters excluding \\ and \" .")
+
+(defun pw-get-char (&optional no-special-chars)
+ "Select a single character at random to be used in a password.
+If `no-special-chars' is t, use only alpha-numeric characters."
+ (let ((selected-charset (append *alphanumerics*
+ (when (null no-special-chars)
+ *special-characters*))))
+ (elt selected-charset (random (length selected-charset)))))
+
+(defun pw-get-chars (password-length &optional no-special-chars)
+ "Generate a list of characters as strings to be made into a password.
+If `no-special-chars' is t, use only alpha-numeric characters."
+ (append (list (pw-get-char no-special-chars))
+ (when (> password-length 1)
+ (pw-get-chars (- password-length 1) no-special-chars))))
+
+(defun generate-password (password-length &optional no-special-chars)
+ "Combine a list of randomly-selected characters into a single string of length given.
+calls `pw-get-chars'. If `no-special-chars' is `t', use only alpha-numeric characters."
+ (apply #'concat (pw-get-chars password-length no-special-chars)))
+
+(defun insert-generated-password (&optional password-length)
+ "Insert a generated password into the current buffer.
+Negative password-length (or negative arg) sets `no-special-chars' for `generate-password'."
+ (interactive "p")
+ (let ((len (if (or (null password-length) (= 1 (abs password-length)))
+ 16
+ (abs password-length)))
+ (no-special-p (and (numberp password-length) (< password-length 0))))
+ (insert (generate-password len no-special-p))))
+
+(provide 're-pass-alike)
+;;; re-pass-alike.el ends here