diff options
| author | Craig Jennings <c@cjennings.net> | 2025-08-14 19:24:49 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-08-14 19:24:49 -0500 |
| commit | 9278ddd4ea1a8b1a4c1edaa8894516e3f48d245b (patch) | |
| tree | 1105519cd55a4ebbb1e91609e6aae7cc3929ddaf /modules | |
| parent | a878e5ae99f750ecbbb723f98ef91d3404189a32 (diff) | |
| download | dotemacs-9278ddd4ea1a8b1a4c1edaa8894516e3f48d245b.tar.gz dotemacs-9278ddd4ea1a8b1a4c1edaa8894516e3f48d245b.zip | |
refactor(system-utils): major refactoring / adding tests
Theme:
Modularize system-utilities into separate modules.
Clean up any typos, buts, and unused variables.
Add some initial ERT tests for new modules created.
Changes:
- Extract file handling into its own module (file-config)
- Extract keyboard macro management into its own module (keyboard-macros)
- Extract buffer burying (instead of killing) into its own module (undead-buffers)
- Extract all date/time config into its own module (chrono-tools)
- Moved keybinding discovery functionality and help into keybindings module
- Combine flyspell and abbrev (spell-check and autocorrect) to flyspell-and-abbrev.el
- Rename epa-config.el to auth-config.el for auth-source and epa settings.
- Refactor `cj/kill-other-window` for more accurate buffer handling.
- Include "*ert*" in the default bury (don't kill) list as killing it kills test runs.
- Bind C-c M-m to inhibit-mouse-mode
- Remove the unused ledger-file variable in user-constants.el.
- Removed obsolete C-x x m, C-x x r, and C-x x d key mappings.
- C-; b r to call cj/rename-buffer-and-file instead of typo’d function
- Other purely cosmetic comment changes to system-utils.el
ERT tests:
- Rename ERT test definitions to include module scopes (file-config, keyboard-macros)
- Add an ERT test for the timer bell's existence.
- Add ERT tests to cover `cj/kill-buffer-or-bury-alive`, prefix-arg behavior, window-killing commands, and bulk operations.
- Add test `authinfo-file` exists Missing authinfo triggers a debug message
- Add test that `gpg2` executable is on the user’s PATH
- Remove outdated authinfo test.
- Add “Run these tests” note where missing.
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/auth-config.el | 57 | ||||
| -rw-r--r-- | modules/chrono-tools.el | 62 | ||||
| -rw-r--r-- | modules/custom-functions.el | 7 | ||||
| -rw-r--r-- | modules/epa-config.el | 31 | ||||
| -rw-r--r-- | modules/file-config.el | 161 | ||||
| -rw-r--r-- | modules/flyspell-and-abbrev.el (renamed from modules/flyspell-config.el) | 41 | ||||
| -rw-r--r-- | modules/keybindings.el | 15 | ||||
| -rw-r--r-- | modules/keyboard-macros.el | 111 | ||||
| -rw-r--r-- | modules/system-defaults.el | 7 | ||||
| -rw-r--r-- | modules/system-utils.el | 382 | ||||
| -rw-r--r-- | modules/undead-buffers.el | 167 | ||||
| -rw-r--r-- | modules/user-constants.el | 12 |
12 files changed, 656 insertions, 397 deletions
diff --git a/modules/auth-config.el b/modules/auth-config.el new file mode 100644 index 00000000..43849f20 --- /dev/null +++ b/modules/auth-config.el @@ -0,0 +1,57 @@ +;; auth-config.el --- Configuration for Authentication Utilities -*- lexical-binding: t; -*- +;; author Craig Jennings <c@cjennings.net> + +;;; Commentary: +;; +;; Configuration for Emacs authentication and GPG integration: + +;; • auth-source +;; – Forces use of your default authinfo file +;; – Disable external GPG agent in favor of Emacs’s own prompt +;; – Enable auth-source debug messages + +;; • Easy PG Assistant (epa) +;; – Force using the ‘gpg2’ executable for encryption/decryption operations + +;;; Code: + +(require 'user-constants) ;; defines authinfo-file location + +;; -------------------------------- Auth Sources ------------------------------- +;; auth sources settings + +(use-package auth-source + :ensure nil ;; built in + :demand t ;; load this package immediately + :config + (setq auth-sources `(,authinfo-file)) + (setenv "GPG_AGENT_INFO" nil) ;; emacs use internal prompt, not gpg agent + (setq auth-source-debug t)) ;; echo debug info to Messages + +;; ----------------------------- Easy PG Assistant ----------------------------- +;; Key management, cryptographic operations on regions and files, dired +;; integration, and automatic encryption/decryption of *.gpg files. + +(use-package epa + :ensure nil ;; built-in + :defer .5 + :config + (setq epg-gpg-program "gpg2")) ;; force use gpg2 (not gpg v.1) + +(provide 'auth-config) +;;; auth-config.el ends here. + +;; --------------------------------- ERT Tests --------------------------------- +;; Run these tests with M-x ert RET t RET + +(require 'ert) +(require 'cl-lib) + +(ert-deftest auth-config/authinfo-file-exists () + "Verify that `authinfo-file` actually exists on disk." + (should (and (stringp authinfo-file) + (file-exists-p authinfo-file)))) + +(ert-deftest auth-config/gpg2-is-on-path () + "Verify that the `gpg2` executable is on the user’s PATH." + (should (executable-find "gpg2"))) diff --git a/modules/chrono-tools.el b/modules/chrono-tools.el new file mode 100644 index 00000000..ae0592f8 --- /dev/null +++ b/modules/chrono-tools.el @@ -0,0 +1,62 @@ +;;; chrono-tools.el --- Config for Date and Time-Related Utils -*- lexical-binding: t; -*- +;; author Craig Jennings <c@cjennings.net> +;;; Commentary: +;; +;; This module centralizes configuration for Emacs time-related tools: +;; +;; – world-clock: predefined city list and custom time format +;; – calendar: quick navigation keybindings by day, month, and year +;; – tmr: lightweight timer setup with sounds, notifications, and history +;; +;;; Code: + +(use-package time + :ensure nil ;; built-in + :defer 0.5 + :bind ("C-x c" . world-clock) + :config + (setq world-clock-list + '(("Pacific/Honolulu" " Honolulu") + ("America/Los_Angeles" " San Francisco, LA") + ("America/Chicago" " Chicago, New Orleans") + ("America/New_York" " New York, Boston") + ("Etc/UTC" " UTC =================") + ("Europe/London" " London, Lisbon") + ("Europe/Paris" " Paris, Berlin, Rome") + ("Europe/Athens" " Athens, Istanbul, Moscow") + ("Asia/Kolkata" " India") + ("Asia/Shanghai" " Shanghai, Singapore") + ("Asia/Tokyo" " Tokyo, Seoul"))) + (setq world-clock-time-format " %a, %d %b @ %I:%M %p %Z")) + +(use-package calendar + :ensure nil ;; built-in + :defer 0.5 + :bind (("M-#" . calendar) + :map calendar-mode-map + ("," . calendar-backward-day) + ("." . calendar-forward-day) + ("<" . calendar-backward-month) + (">" . calendar-forward-month) + ("M-," . calendar-backward-year) + ("M-." . calendar-forward-year))) + +(use-package tmr + :defer 0.5 + :bind ("M-t" . tmr-prefix-map) + :config + (setq tmr-sound-file "/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga" + tmr-notification-urgency 'normal + tmr-descriptions-list 'tmr-description-history)) + + +(provide 'chrono-tools) +;;; chrono-tools.el ends here. + +;; --------------------------------- ERT Tests --------------------------------- +;; Run these tests with M-x ert RET t RET + +(ert-deftest chrono-tools/tmr-sound-file-exists () + "Test that `tmr-sound-file` points to an existing file." + (require 'tmr) + (should (file-exists-p tmr-sound-file))) diff --git a/modules/custom-functions.el b/modules/custom-functions.el index efc2d4e2..846475cb 100644 --- a/modules/custom-functions.el +++ b/modules/custom-functions.el @@ -548,7 +548,6 @@ Uses `sortable-time-format' for the formatting the date/time." (message "Buffer '%s' is not visiting a file!" name) (progn (copy-file filename newname 1) (delete-file filename) (set-visited-file-name newname) (set-buffer-modified-p nil) t)))) -(global-set-key (kbd "C-x x m") 'cj/move-buffer-and-file) ;; RENAME BUFFER + FILE (defun cj/rename-buffer-and-file (new-name) @@ -566,8 +565,7 @@ Uses `sortable-time-format' for the formatting the date/time." (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) - (set-buffer-modified-p nil)))))) -(global-set-key (kbd "C-x x r") 'cj/rename-buffer-and-file) + (set-buffer-modified-p nil)))))) ;; DELETE BUFFER + FILE (defun cj/delete-buffer-and-file () @@ -581,7 +579,6 @@ Uses `sortable-time-format' for the formatting the date/time." (delete-file filename t) (message "Deleted file %s" filename) (kill-buffer)))))) -(global-set-key (kbd "C-x x d") 'cj/delete-buffer-and-file) ;; ------------------------------- Ordinal Suffix ------------------------------ ;; add the proper ordinal to a number (e.g., 1st, 2nd, 3rd, 4th). @@ -656,7 +653,7 @@ Uses `sortable-time-format' for the formatting the date/time." (global-set-key (kbd "C-; i t") 'cj/insert-sortable-time) (global-set-key (kbd "C-; i d") 'cj/insert-sortable-date) ;; buffer and file operations -(global-set-key (kbd "C-; b r") 'cj/renameq-buffer-and-file) +(global-set-key (kbd "C-; b r") 'cj/rename-buffer-and-file) (global-set-key (kbd "C-; b d") 'cj/delete-buffer-and-file) (global-set-key (kbd "C-; b m") 'cj/move-buffer-and-file) ;; copy link to source file diff --git a/modules/epa-config.el b/modules/epa-config.el deleted file mode 100644 index 1b7ae21b..00000000 --- a/modules/epa-config.el +++ /dev/null @@ -1,31 +0,0 @@ -;;; epa-config.el --- EasyPG Configuration -*- lexical-binding: t; -*- -;; author Craig Jennings <c@cjennings.net> - -;;; Commentary: -;; - -;;; Code: - -;; -------------------------------- Auth Sources ------------------------------- -;; auth sources settings - -(use-package auth-source - :ensure nil ;; built in - :demand t ;; load this package early - :config - (setq auth-sources `(,authinfo-file)) - (setenv "GPG_AGENT_INFO" nil) ;; emacs use internal prompt, not gpg agent - (setq auth-source-debug t)) ;; echo debug info to Messages - -;; ----------------------------- Easy PG Assistant ----------------------------- -;; Key management, cryptographic operations on regions and files, dired -;; integration, and automatic encryption/decryption of *.gpg files. - -(use-package epa - :ensure nil ;; built-in - :defer .5 - :config - (setq epg-gpg-program "gpg2")) ;; force use gpg2 (not gpg v.1) - -(provide 'epa-config) -;;; epa-config.el ends here. diff --git a/modules/file-config.el b/modules/file-config.el new file mode 100644 index 00000000..cf5ef715 --- /dev/null +++ b/modules/file-config.el @@ -0,0 +1,161 @@ +;;; file-config.el --- Open Files Using Default OS Handler -*- lexical-binding: t; -*- +;; author Craig Jennings <c@cjennings.net> +;; +;;; Commentary: +;; +;; This library provides a simple mechanism for opening files with specific +;; extensions using your operating system’s default application rather than +;; visiting them in an Emacs buffer. It offers: + +;; • A simple method to run a command on the current buffer's file +;; "C-c x o" bound to cj/open-this-file-with +;; • A customizable list =default-open-extensions= of file‐type suffixes +;; (e.g. “pdf”, “docx”, “png”) that should be handled externally. +;; • A function =default-open-file= (and its helper commands) which will +;; launch the matching file in the OS’s default MIME handler. +;; • Integration with =find-file-hook= so that any file whose extension +;; appears in =default-open-extensions= is automatically opened externally +;; upon visit. +;; • Optional interactive commands for manually invoking an external open on +;; point or on a user-chosen file. + +;;; Code: + +(require 'host-environment) ;; environment information functions + +;; ------------------------------- Open File With ------------------------------ + +(defun cj/open-this-file-with (command) + "Asynchronously run COMMAND on the current buffer's file." + (interactive "MOpen with program: ") + (let ((display-buffer-alist + '(("\\*Async Shell Command\\*" display-buffer-no-window)))) + (async-shell-command (format "%s \"%s\"" command buffer-file-name)))) +(global-set-key (kbd "C-c x o") #'cj/open-this-file-with) + +;; ------------------------- Use Default File Handlers ------------------------- + +(defun cj/xdg-open-command () + "Return the OS-default \"open\" command for this host. +Signals an error if the host is unsupported." + (cond + ((env-linux-p) "xdg-open") + ((env-macos-p) "open") + ((env-windows-p) "start") + (t (error "cj/xdg-open: unsupported host environment")))) + +(defun cj/xdg-open (&optional filename) + "Open FILENAME (or the file at point) with the OS default handler. +Logs output and exit code to buffer *cj-xdg-open.log*." + (interactive) + (let* ((file (expand-file-name + (or filename + (dired-file-name-at-point)))) + (cmd (cj/xdg-open-command)) + (logbuf (get-buffer-create "*cj-xdg-open.log*")) + exit-code) + (with-current-buffer logbuf + (goto-char (point-max)) + (insert (format-time-string "[%Y-%m-%d %H:%M:%S] " (current-time))) + (insert (format "Running `%s %s`\n" cmd file)) + (setq exit-code + (call-process cmd nil logbuf t file)) + (insert (format "Exit code: %d\n\n" exit-code))) + exit-code)) + +(defun cj/find-file-auto (orig-fun &rest args) + "If file is media or Office, open via xdg-open, else call ORIG-FUN with ARGS." + (let ((file (car args)) + (exts '("\\.avi\\'" + "\\.mp4\\'" + "\\.mkv\\'" + "\\.mov\\'" + "\\.mp3\\'" + "\\.ogg\\'" + "\\.docx?\\'" + "\\.pptx?\\'" + "\\.xlsx?\\'"))) + (if (cl-find-if (lambda (re) (string-match re file)) exts) + (cj/xdg-open file) + (apply orig-fun args)))) +(advice-add 'find-file :around #'cj/find-file-auto) + +(provide 'file-config) +;;; file-config.el ends here. + +;; --------------------------------- ERT Tests --------------------------------- +;; Run these tests with M-x ert RET t RET + +(require 'ert) +(require 'cl-lib) + + +(ert-deftest file-config/open-this-file-with-invokes-async-shell-command () + "Ensure `cj/open-this-file-with` calls `async-shell-command` with the +program name and the buffer's file name, properly quoted." + (let* ((test-file (expand-file-name "space in name.txt" + temporary-file-directory)) + called-cmd) + ;; Create a temp buffer and pretend its file is TEST-FILE + (with-temp-buffer + (set (make-local-variable 'buffer-file-name) test-file) + ;; Override `async-shell-command` to capture its argument + (cl-letf (((symbol-function 'async-shell-command) + (lambda (cmd &rest _) + (setq called-cmd cmd)))) + (cj/open-this-file-with "myprog"))) + ;; Now assert it was called with: myprog "full/path/to/space in name.txt" + (should (string= called-cmd + (format "myprog \"%s\"" test-file))))) + +(ert-deftest file-config/find-file-auto-opens-matching-extension () + "cj/find-file-auto should invoke `cj/xdg-open' when the filename has a media/Office extension." + (let* ((called-file nil) + (test-file "/tmp/video.mp4") + ;; stash the real function so we can restore it later + (orig-xdg-open (symbol-function 'cj/xdg-open))) + (cl-letf (((symbol-function 'cj/xdg-open) + (lambda (file) + (setq called-file file) + ;; pretend we returned an exit code + 0))) + (unwind-protect + (progn + ;; call the advice wrapper as if Emacs were doing (find-file test-file) + (cj/find-file-auto + (lambda (_file) (error "Should not call original find-file")) + test-file) + (should (equal called-file test-file))) + ;; restore + (fset 'cj/xdg-open orig-xdg-open))))) + +(ert-deftest file-config/find-file-auto-falls-back-for-nonmatching () + "cj/find-file-auto should fall back to the original FIND-FILE when the extension does not match." + (let ((called-file nil) + (test-file "/tmp/document.txt")) + (cj/find-file-auto + (lambda (file) + (setq called-file file) + ;; pretend that visiting succeeded + t) + test-file) + (should (equal called-file test-file)))) + +(ert-deftest file-config/xdg-open-logs-and-returns-exit-code () + "cj/xdg-open should call the OS command, log its invocation+exit code, and return that code." + (let* ((dummy-file (make-temp-file "cj-test" nil ".foo")) + (logbuf (get-buffer-create "*cj-xdg-open.log*")) + ;; override the command to something harmless + (orig-cmd-fn (symbol-function 'cj/xdg-open-command))) + (cl-letf (((symbol-function 'cj/xdg-open-command) + (lambda () "true"))) + (unwind-protect + (let ((code (cj/xdg-open dummy-file))) + (should (= code 0)) + (with-current-buffer logbuf + (goto-char (point-min)) + (should (search-forward (format "`true %s`" dummy-file) nil t)) + (should (search-forward "Exit code: 0" nil t)))) + ;; cleanup + (kill-buffer logbuf) + (fset 'cj/xdg-open-command orig-cmd-fn))))) diff --git a/modules/flyspell-config.el b/modules/flyspell-and-abbrev.el index 89fd25a1..bcc8be69 100644 --- a/modules/flyspell-config.el +++ b/modules/flyspell-and-abbrev.el @@ -1,40 +1,40 @@ -;;; flyspell-config.el --- Spell Check Configuration -*- lexical-binding: t; -*- +;;; flyspell-and-abbrev.el --- Spell Check Configuration -*- lexical-binding: t; -*- ;; author Craig Jennings <c@cjennings.net> ;;; Commentary: -;; Spell-Checking: Flyspell - +;; WORKFLOW: ;; C-' is now my main interface for all spell checking. - +;; ;; The workflow is that it finds the nearest misspelled word above where the ;; cursor is, allows for saving or correcting, then stops. You may proceed to ;; the next misspelling by selecting C-' again. - +;; +;; Use M-o to get to 'other options', like saving to your personal dictionary. +;; ;; Flyspell will automatically run in a mode appropriate for the buffer type ;; - if it's a programming mode, it will only check comments ;; - if in text mode, it will check everything ;; - otherwise it will turn off. ;; This check happens on every mode switch. - +;; ;; If you want flyspell on in another mode (say fundamental mode), or you want ;; to turn it off, you can toggle flyspell's state with 'C-c f' - +;; ;; The nicest thing is that each spell correction creates an abbrev. This ;; essentially is a shortcut that expands that same misspelling to the correct ;; spelling the next time it's typed. That idea comes courtesy Artur Malabarba, ;; and it's increased my overall typing speed. - +;; ;; Original idea here: ;; http://endlessparentheses.com/ispell-and-abbrev-the-perfect-auto-correct.html - +;; ;; The code below is my refactoring of Artur Malabarba's code, and using ;; flyspell rather than ispell. - ;; -;; Use M-o to get to 'other options', like saving to your personal dictionary. - -;; Note that the keybinding typically taken for the flyspell-mode-map "C-;" has +;; NOTES: +;; +;; FYI, the keybinding typically taken for the flyspell-mode-map "C-;" has ;; been deliberately hijacked in custom-functions.el for my personal-keymap. ;; This is the code run there: @@ -43,8 +43,17 @@ ;;; Code: -;; ---------------------------- Ispell And Flyspell ---------------------------- +;; ----------------------------------- Abbrev ---------------------------------- +(use-package abbrev-mode + :ensure nil + :defer 0.5 + :custom + (abbrev-file-name (concat user-emacs-directory "assets/abbrev_defs")) + :config + (abbrev-mode 1)) + +;; ---------------------------- Ispell And Flyspell ---------------------------- (use-package ispell :defer .5 @@ -198,5 +207,5 @@ argument is provided, when it's created in the global dictionary." (define-key global-map (kbd "C-'") 'cj/flyspell-then-abbrev) -(provide 'flyspell-config) -;;; flyspell-config.el ends here. +(provide 'flyspell-and-abbrev) +;;; flyspell-and-abbrev.el ends here. diff --git a/modules/keybindings.el b/modules/keybindings.el index af600999..a8b3eb41 100644 --- a/modules/keybindings.el +++ b/modules/keybindings.el @@ -101,6 +101,21 @@ (define-key jump-to-keymap (kbd "I") #'(lambda () (interactive) (find-file emacs-init-file))) + +;; ---------------------------- Keybinding Discovery --------------------------- + +(use-package free-keys + :defer 1 + :bind ("C-h C-k" . free-keys)) + +(use-package which-key + :defer 1 + :config + (setq which-key-idle-delay 3.0 + which-key-popup-type 'side-window) + (which-key-setup-side-window-right-bottom) + (which-key-mode 1)) + ;; ---------------------------- General Keybindings ---------------------------- ;; Avoid hostile bindings diff --git a/modules/keyboard-macros.el b/modules/keyboard-macros.el new file mode 100644 index 00000000..cff25b39 --- /dev/null +++ b/modules/keyboard-macros.el @@ -0,0 +1,111 @@ +;;; keyboard-macros.el --- Keyboard Macro Management -*- lexical-binding: t; -*- +;; author Craig Jennings <c@cjennings.net> + +;;; Commentary: +;; +;; This library provides a simple, end-user–focused interface for +;; creating, naming, saving, and replaying keyboard macros in Emacs. +;; All commands are built on top of the built-in =kmacro= machinery, but +;; add a lightweight workflow and persistence across sessions. +;; +;; User Workflow: +;; +;; 1. Start recording with C-F3 (or M-x cj/kbd-macro-start-or-end) +;; This toggles macro recording on. +;; Now you can perform all the edits you want recorded in the macro. +;; +;; 2. Stop recording with C-F3 (or M-x cj/kbd-macro-start-or-end) +;; This stops recording and the macro becomes the “last keyboard macro.” +;; +;; 3. Replay your macro <f3> (or M-x call-last-kbd-macro) +;; +;; 4. Name your macro with M-<F3> +;; You will be prompted for a short name (e.g. =align-comments=, +;; =cleanup-trail-spaces=). This name is how you’ll refer to it later. +;; +;; +;; 5. Recall that macro later with M-x [the name you gave the macro] +;; +;; 6. View all your saved macros with s-<f3> (super-f3) +;; +;; 7. All macros reload at startup automatically. +;; When this library is loaded, it will look for the save file and +;; re-establish all your named macros in your current session. +;; +;;; Code: + +(require 'user-constants) ;; definition of sync-dir constant is here. + +(defvar macros-file (concat sync-dir "macros.el") + "The location of the macros file for recorded saved macros via M-f3.") + +(defun ensure-macros-file (file) + "Ensure FILE exists and its first line enables lexical-binding." + (unless (file-exists-p file) + (with-temp-file file + (insert ";;; -*- lexical-binding: t -*-\n")))) + +(when (file-exists-p macros-file) + (load macros-file)) + +(defun cj/kbd-macro-start-or-end () + "Toggle start/end of keyboard macro definition." + (interactive) + (if defining-kbd-macro + (end-kbd-macro) + (start-kbd-macro nil))) +(global-set-key (kbd "C-<f3>") #'cj/kbd-macro-start-or-end) +(global-set-key (kbd "<f3>") #'call-last-kbd-macro) + +(defun cj/save-maybe-edit-macro (name) + "Save last macro as NAME in `macros-file'; edit if prefix arg." + (interactive "SName of macro: ") + (kmacro-name-last-macro name) + (find-file macros-file) + (goto-char (point-max)) + (newline) + (insert-kbd-macro name) + (newline) + (save-buffer) + (switch-to-buffer (other-buffer (current-buffer) 1)) + (when current-prefix-arg + (find-file macros-file) + (goto-char (point-max))) + name) +(global-set-key (kbd "M-<f3>") #'cj/save-maybe-edit-macro) + +(global-set-key (kbd "s-<f3>") (lambda () (interactive) (find-file macros-file))) + +(defun ensure-macros-file (file) + "Ensure FILE exists and its first line enables lexical-binding." + (unless (file-exists-p file) + (with-temp-file file + (insert ";;; -*- lexical-binding: t -*-\n")))) + +(when (file-exists-p macros-file) + (load macros-file)) + +(provide 'keyboard-macros) +;;; keyboard-macros.el ends here. + + +;; --------------------------------- ERT Tests --------------------------------- +;; Run these tests with M-x ert RET t RET + +(require 'ert) + +(ert-deftest keyboard-macros/ensure-macros-file-creates-header () + "ensure-macros-file creates FILE with the right header." + (let ((file (make-temp-file "macros-test" nil ".el"))) + (unwind-protect + (progn + (delete-file file) + (should-not (file-exists-p file)) + (ensure-macros-file file) + (should (file-exists-p file)) + (let ((contents (with-temp-buffer + (insert-file-contents file) + (buffer-string)))) + (should (string= contents ";;; -*- lexical-binding: t -*-\n")))) + (when (file-exists-p file) + (delete-file file))))) diff --git a/modules/system-defaults.el b/modules/system-defaults.el index b984b78c..c52b3e04 100644 --- a/modules/system-defaults.el +++ b/modules/system-defaults.el @@ -142,15 +142,16 @@ Return non-nil to indicate the warning was handled." ;; disabling mouse prevents accidental mouse moves modifying text (use-package inhibit-mouse - :commands inhibit-mouse-mode :hook (after-init . inhibit-mouse-mode) :custom (inhibit-mouse-adjust-mouse-highlight t) (inhibit-mouse-adjust-show-help-function t) + :bind + ("C-c M-m" . inhibit-mouse-mode) ;; toggle with C-c M-m :config (if (daemonp) - (add-hook 'server-after-make-frame-hook #'inhibit-mouse-mode) - (inhibit-mouse-mode 1))) + (add-hook 'server-after-make-frame-hook #'inhibit-mouse-mode) + (inhibit-mouse-mode 1))) ;; ------------------------------- Be Quiet(er)! ------------------------------- ;; reduces "helpful" instructions that distract Emacs power users. diff --git a/modules/system-utils.el b/modules/system-utils.el index e0121f0f..53992481 100644 --- a/modules/system-utils.el +++ b/modules/system-utils.el @@ -4,371 +4,89 @@ ;;; Code: +(require 'cl-lib) +(require 'host-environment) -;; ---------------------------------- Xdg-Open --------------------------------- -;; open specific file extensions with the system's default mime-type handler - -(defun cj/xdg-open (&optional filename) - (interactive) - (let ((command (cond ((eq system-type 'gnu/linux) "xdg-open") - ((eq system-type 'darwin) "open") - ((eq system-type 'windows-nt) "start") - (t "")))) - (with-current-buffer (get-buffer-create "xdg-open.log") - (goto-char (point-max)) - (insert (format "Running command %s\n" command)) - (let ((exit-code (call-process command nil t t (expand-file-name - (or filename (dired-file-name-at-point)))))) - (insert (format "Exit code: %s\n" exit-code)))))) - -(defun cj/find-file-auto (orig-fun &rest args) - (let ((filename (car args))) - (if (cl-find-if - (lambda (regexp) (string-match regexp filename)) - '("\\.avi\\'" - "\\.mp4\\'" - "\\.divx\\'" - "\\.flv\\'" - "\\.mkv\\'" - "\\.mpeg\\'" - "\\.mov\\'" - "\\.wav\\'" - "\\.webm\\'" - "\\.mp3\\'" - "\\.opus\\'" - "\\.ogg\\'" - "\\.flac\\'" - "\\.docx?\\'" - "\\.pptx?\\'" - "\\.xlsx?\\'" - )) - (progn - (cj/xdg-open filename)) - (progn - (apply orig-fun args))))) - -(advice-add 'find-file :around 'cj/find-file-auto) - -;; ---------------------------------- Ibuffer ---------------------------------- - -(global-set-key [remap list-buffers] 'ibuffer) ;; use ibuffer, not list-buffers - -(use-package nerd-icons-ibuffer - :defer .5 - :after nerd-icons - :hook (ibuffer-mode . nerd-icons-ibuffer-mode) - :config - (setq nerd-icons-ibuffer-icon t) - (setq nerd-icons-ibuffer-color-icon t) - (setq nerd-icons-ibuffer-human-readable-size t)) - -;; ------------------------ Killing Buffers And Windows ------------------------ -;; Accidentally killing buffers can lose data. these functions override common -;; buffer killing functions and buries buffers on the -;; 'cj/buffer-bury-alive-list' list rather than killing them. Allows for -;; interactive adding to the 'cj/buffer-bury-alive-list' via 'C-u C-x k' - -;; BUFFER BURY ALIVE LIST -(defvar cj/buffer-bury-alive-list '("*dashboard*" - "*scratch*" - "*Messages*" - "*ChatGPT*") - "Buffers that shouldn't be killed, but buried instead.") - -;; KILL BUFFER AND WINDOW -(defun cj/kill-buffer-and-window () - "Kill current buffer and window. -Buries buffers instead if they are on the cj/buffer-bury-alive-list." - (interactive) - (let ((target-buffer (current-buffer))) - (delete-window) - (cj/kill-buffer-or-bury-alive target-buffer))) -(global-set-key (kbd "M-C") 'cj/kill-buffer-and-window) - -;; KILL OTHER WINDOW -(defun cj/kill-other-window () - "Close the next window and kill any buffer in it. -Buries buffers instead if they are on the cj/buffer-bury-alive-list." - (interactive) - (other-window 1) - (let ((target-buffer (current-buffer))) - (if (not (one-window-p)) (delete-window)) - (cj/kill-buffer-or-bury-alive target-buffer))) -(global-set-key (kbd "M-O") 'cj/kill-other-window) - -;; KILL ALL OTHER BUFFERS AND WINDOWS -(defun cj/kill-all-other-buffers-and-windows () - "Save buffers, then kill all other buffers and windows. -Buries buffers instead if they are on the cj/buffer-bury-alive-list." - (interactive) - (save-some-buffers) - (delete-other-windows) - (mapc 'cj/kill-buffer-or-bury-alive (delq (current-buffer) (buffer-list)))) -(global-set-key (kbd "M-M") 'cj/kill-all-other-buffers-and-windows) - -;; KILL BUFFER OR BURY ALIVE -(defun cj/kill-buffer-or-bury-alive (target-buffer) - "Bury buffers on the bury-instead-list rather than killing them. -With a prefix, add the TARGET-BUFFER to \='cj/buffer-bury-alive-list\='." - (interactive "bKill or Add to bury (don't kill) buffer list: ") - (with-current-buffer target-buffer - (if current-prefix-arg - (progn - (add-to-list 'cj/buffer-bury-alive-list (buffer-name (current-buffer))) - (message "Added %s to bury-alive-list" (buffer-name (current-buffer)))) - (if (member (buffer-name (current-buffer)) cj/buffer-bury-alive-list) - (bury-buffer) - (kill-buffer (current-buffer)))))) -(global-set-key [remap kill-buffer] #'cj/kill-buffer-or-bury-alive) - -;; --------------------------- Emacs Server Shutdown --------------------------- -;; shuts down the Emacs server. useful with emacsclient. - -(defun server-shutdown () - "Save buffers, quit, and shutdown (kill) server." - (interactive) - (save-some-buffers) - (kill-emacs)) -(global-set-key (kbd "C-<f10>") 'server-shutdown) -(global-set-key (kbd "<f10>") 'save-buffers-kill-terminal) - -;; --------------------------------- Free Keys --------------------------------- -;; Displays free keybindings. Allows indicating a specific key prefix. - -(use-package free-keys - :defer 1 - :bind ("C-h C-k" . free-keys)) - -;; --------------------------------- Sudo Edit --------------------------------- -;; Edit a file the current buffer is visiting as sudo user. +;; ---------------------------- Edit A File With Sudo ---------------------------- (use-package sudo-edit :defer 1 :bind ("C-x M-f" . sudo-edit)) -;; --------------------------- Open File With Command -------------------------- -;; opens the current buffer's file with a command. Prompts if interactive. - -(defun cj/open-file-with-command (command) - "Asynchronously open the file assocated with the current buffer with COMMAND. -Don't automatically display output buffers, but keep them in buffer list." +(defun cj/open-file-with (command) + "Asynchronously run COMMAND on the current buffer's file." (interactive "MOpen with program: ") - (let ((display-buffer-keywords - '(("*Async Shell Command*" display-buffer-no-window (nil))))) - (add-to-list 'display-buffer-alist display-buffer-keywords)) - (async-shell-command (format "%s \"%s\"" command buffer-file-name))) + (let ((display-buffer-alist + '(("\\*Async Shell Command\\*" display-buffer-no-window)))) + (async-shell-command (format "%s \"%s\"" command buffer-file-name)))) -;; --------------------------------- Open With --------------------------------- -;; automatically opens files with specific programs using file extensions. +;; ------------------------------ Server Shutdown ------------------------------ -(use-package openwith - :defer 1 - :config - (setq openwith-associations - (list - (list (openwith-make-extension-regexp - '("mpg" "mpeg" "mp3" "mp4" "webm" "avi" "wmv" "wav" "mov" "flv" "ogm" "ogg" "mkv")) - "mpv" - '(file)) - ;; removed jpg from list below as dashboard was opening nxiv - (list (openwith-make-extension-regexp - '("xbm" "pbm" "pgm" "ppm" "pnm" "png" "gif" "bmp" "tif")) - "nsxiv" - '(file)) - (list (openwith-make-extension-regexp - '("odt" "odf" "xls" "xlsx" "doc" "docx")) - "libreoffice" - '(file)) - (list (openwith-make-extension-regexp - '("cbr" "cbz")) - "zathura" - '(file))))) +(defun server-shutdown () + "Save buffers, kill Emacs and shutdown the server." + (interactive) + (save-some-buffers) + (kill-emacs)) +(global-set-key (kbd "C-<f10>") #'server-shutdown) +(global-set-key (kbd "<f10>") #'save-buffers-kill-terminal) -;; --------------------------------- Which Key --------------------------------- -;; displays key bindings following your currently entered incomplete command +;; ------------------------ List Buffers With Nerd Icons ----------------------- -(use-package which-key - :defer 1 +(global-set-key [remap list-buffers] #'ibuffer) +(use-package nerd-icons-ibuffer + :defer 0.5 + :after nerd-icons + :hook (ibuffer-mode . nerd-icons-ibuffer-mode) :config - (setq which-key-idle-delay 3.0) - (setq which-key-popup-type 'side-window) - (add-to-list 'which-key-replacement-alist '((nil . "digit-argument") . t)) - (which-key-setup-side-window-right-bottom) - (which-key-mode 1)) - -;; ------------------------------- Scratch Buffer ------------------------------ -;; make the scratch buffer joyful, org-mode by default, and persistent. -;; coding tip: org babel + code blocks allows for more flexibility and comments. - -(defvar scratch-emacs-version-and-system (concat ";; Welcome to Emacs " - emacs-version " running on " - system-configuration ".\n")) -(defvar scratch-greet (concat ";; Emacs ♥ you, " user-login-name ". " - "Happy Hacking!\n\n")) - - -(setq initial-scratch-message (concat scratch-emacs-version-and-system - scratch-greet)) - -;; make scratch buffer an org-mode buffer + (setq nerd-icons-ibuffer-icon t + nerd-icons-ibuffer-color-icon t + nerd-icons-ibuffer-human-readable-size t)) + +;; -------------------------- Scratch Buffer Happiness ------------------------- + +;; Customize the scratch buffer +(defvar scratch-emacs-version-and-system + (concat ";; Welcome to Emacs " emacs-version + " running on " system-configuration ".\n")) +(defvar scratch-greet + (concat ";; Emacs ♥ you, " user-login-name ". Happy Hacking!\n\n")) +(setq initial-scratch-message + (concat scratch-emacs-version-and-system scratch-greet)) (setq initial-major-mode 'org-mode) -;; -------------------------------- World Clock -------------------------------- -;; displays current time in various timezones - -(use-package time - :ensure nil ;; built-in - :defer .5 - :bind ("C-x c" . world-clock) - :config - (setq world-clock-list - '(("Pacific/Honolulu" " Honolulu") - ("America/Los_Angeles" " San Francisco, Los Angeles") - ("America/Chicago" " New Orleans, Chicago") - ("America/New_York" " New York, Boston") - ("Etc/UTC" " UTC ====================================") - ("Europe/London" " London, Lisbon") - ("Europe/Paris" " Paris, Berlin, Rome, Barcelona") - ("Europe/Athens" " Athens, Istanbul, Kyiv, Moscow, Tel Aviv") - ("Asia/Yerevan" " Yerevan") - ("Asia/Kolkata" " India") - ("Asia/Shanghai" " Shanghai, Singapore") - ("Asia/Tokyo" " Tokyo, Seoul"))) - (setq world-clock-time-format " %a, %d %b @ %I:%M %p %Z")) - -;; ---------------------------------- Calendar --------------------------------- -;; providing simple shortcuts -;; backward and forward day are ',' and '.' -;; shift & meta moves by week or year -;; C-. jumps to today -;; consistent with scheduling in org-mode - -(use-package calendar - :defer .5 - :ensure nil ;; built-in - :bind - ("M-#" . calendar) - (:map calendar-mode-map - ("," . calendar-backward-day) - ("." . calendar-forward-day) - ("<" . calendar-backward-month) - (">" . calendar-forward-month) - ("M-," . calendar-backward-year) - ("M-." . calendar-forward-year))) - ;; --------------------------------- Dictionary -------------------------------- -;; install Webster's dictionary in StarDict format -;; http://jsomers.net/blog/dictionary (use-package sdcv :defer 1 - :bind ("C-h d" . 'sdcv-search-input)) - -;; ------------------------------ -Keyboard Macros ----------------------------- -;; note that this leverages simple, easy to remember shortcuts -;; -;; start a macro with C-f3, perform your actions, then finish with C-f3 (same key) -;; run your macro by pressing f3 -;; if you wish to save and edit it (provide a keybinding), use C-u M-f3 -;; otherwise, jsut save it with M-f3 and call it with M-x (name you provided) - -(defun kbd-macro-start-or-end () - "Begins a keyboard macro definition, or if one's in progress, finish it." - (interactive) - (if defining-kbd-macro - (end-kbd-macro) - (start-kbd-macro nil))) -(global-set-key (kbd "C-<f3>") 'kbd-macro-start-or-end) -(global-set-key (kbd"<f3>") 'call-last-kbd-macro) -(global-set-key (kbd"M-<f3>") 'cj/save-maybe-edit-macro) - -(defun cj/save-maybe-edit-macro (name) - "Save a macro in `macros-file'. -Save the last defined macro as NAME at the end of your `macros-file' -The `macros-file' is defined in the constants section of the `init.el'). -The function offers the option to open the `macros-file' for editing when called -with a prefix argument." - (interactive "SName of the macro (w/o spaces): ") - (kmacro-name-last-macro name) - (find-file macros-file) - (goto-char (point-max)) - (newline) - (insert-kbd-macro name) - (newline) - ;; Save changes and switch back to previous buffer - (save-buffer) - (switch-to-buffer (other-buffer (current-buffer) 1)) - ;; Check for the prefix argument and open the macros-file to edit - (if current-prefix-arg - (progn - (find-file macros-file) - (goto-char (point-max)))) - ;; Return name for convenience - name) - -;; now load all saved macros, creating an empty macro-file if it doesn't exist. -(if (file-exists-p macros-file) - (load macros-file) - (progn - (write-region ";;; -*- lexical-binding: t -*-\n" nil macros-file) - (message "Saved macros file not found, so created: %s" macros-file))) - -;; -------------------------------- Abbrev Mode -------------------------------- -;; word abbreviations mode. used to auto-correct spelling (see flyspell-config) - -(use-package abbrev-mode - :ensure nil ;; built-in - :defer .5 - :custom - (abbrev-file-name (concat user-emacs-directory "assets/abbrev_defs")) - :config - (abbrev-mode)) ;; use abbrev mode everywhere + :bind ("C-h d" . sdcv-search-input)) ;; -------------------------------- Log Silently ------------------------------- -;; utility to silently log to the Messages buffer (for debugging/warning) (defun cj/log-silently (text) - "Send TEXT to the Messages buffer bypassing the echo area." - (let ((inhibit-read-only t) - (messages-buffer (get-buffer "*Messages*"))) - (with-current-buffer messages-buffer - (goto-char (point-max)) - (unless (bolp) - (insert "\n")) - (insert text) - (unless (bolp) - (insert "\n"))))) + "Append TEXT to *Messages* buffer without echoing in the minibuffer." + (let ((inhibit-read-only t)) + (with-current-buffer (get-buffer-create "*Messages*") + (goto-char (point-max)) + (unless (bolp) (insert "\n")) + (insert text) + (unless (bolp) (insert "\n"))))) -;; ----------------------------------- Proced ---------------------------------- -;; yes, there's a process monitor built-into Emacs. It's just not configured. +;; ------------------------------ Process Monitor ------------------------------ (use-package proced - :defer .5 - :ensure nil ;;built-in + :ensure nil ;; built-in + :defer 0.5 :commands proced :bind ("C-M-p" . proced) :custom (proced-auto-update-flag t) - (proced-goal-attribute nil) (proced-show-remote-processes t) (proced-enable-color-flag t) (proced-format 'custom) :config - (add-to-list - 'proced-format-alist - '(custom user pid ppid sess tree pcpu pmem rss start time state (args - comm)))) - -;; ------------------------------------ TMR ------------------------------------ - -(use-package tmr - :defer .5 - :bind ("M-t" . tmr-prefix-map) - :config - (setq tmr-sound-file - "/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga") - (setq tmr-notification-urgency 'normal) - (setq tmr-descriptions-list 'tmr-description-history)) + (add-to-list 'proced-format-alist + '(custom user pid ppid sess tree pcpu pmem rss start time + state (args comm)))) (provide 'system-utils) ;;; system-utils.el ends here diff --git a/modules/undead-buffers.el b/modules/undead-buffers.el new file mode 100644 index 00000000..fbfc2782 --- /dev/null +++ b/modules/undead-buffers.el @@ -0,0 +1,167 @@ +;;; undead-buffers.el --- Bury Rather Than Kill These Buffers -*- lexical-binding: t; -*- + +;;; Commentary: +;; +;; This library allows for “burying” selected buffers instead of killing them. +;; Since they won't be killed, I'm calling them "undead buffers". +;; +;; The main function cj/kill-buffer-or-bury-alive replaces kill-buffer. +;; +;; Additional helper commands and key bindings: +;; - M-C (=cj/kill-buffer-and-window=): delete this window and bury/kill its buffer. +;; - M-O (=cj/kill-other-window=): delete the next window and bury/kill its buffer. +;; - M-M (=cj/kill-all-other-buffers-and-windows=): kill or bury all buffers except +;; the current one and delete all other windows. +;; +;; Add to the list of "undead buffers" by adding to the cj/buffer-bury-alive-list +;; variable. +;; +;;; Code: + +(defvar cj/buffer-bury-alive-list + '("*dashboard*" "*scratch*" "*Messages*" "*ert*" "*AI-Assistant*") + "Buffers to bury instead of killing.") + +(defun cj/kill-buffer-or-bury-alive (buffer) + "Kill BUFFER or bury it if it's in `cj/buffer-bury-alive-list'." + (interactive "bBuffer to kill or bury: ") + (with-current-buffer buffer + (if current-prefix-arg + (progn + (add-to-list 'cj/buffer-bury-alive-list (buffer-name)) + (message "Added %s to bury-alive-list" (buffer-name))) + (if (member (buffer-name) cj/buffer-bury-alive-list) + (bury-buffer) + (kill-buffer))))) +(global-set-key [remap kill-buffer] #'cj/kill-buffer-or-bury-alive) + +(defun cj/kill-buffer-and-window () + "Delete window and kill or bury its buffer." + (interactive) + (let ((buf (current-buffer))) + (delete-window) + (cj/kill-buffer-or-bury-alive buf))) +(global-set-key (kbd "M-C") #'cj/kill-buffer-and-window) + +(defun cj/kill-other-window () + "Delete the next window and kill or bury its buffer." + (interactive) + (other-window 1) + (let ((buf (current-buffer))) + (unless (one-window-p) + (delete-window)) + (cj/kill-buffer-or-bury-alive buf))) +(global-set-key (kbd "M-O") #'cj/kill-other-window) + +(defun cj/kill-all-other-buffers-and-windows () + "Kill or bury all other buffers, then delete other windows." + (interactive) + (save-some-buffers) + (delete-other-windows) + (mapc #'cj/kill-buffer-or-bury-alive + (delq (current-buffer) (buffer-list)))) +(global-set-key (kbd "M-M") #'cj/kill-all-other-buffers-and-windows) + +(provide 'undead-buffers) +;;; undead-buffers.el ends here. + +;; --------------------------------- ERT Tests --------------------------------- +;; Run these tests with M-x ert RET t RET + +(require 'ert) +(require 'cl-lib) + +(ert-deftest undead-buffers/kill-or-bury-when-not-in-list-kills () + "cj/kill-buffer-or-bury-alive should kill a buffer not in `cj/buffer-bury-alive-list'." + (let* ((buf (generate-new-buffer "test-not-in-list")) + (orig (copy-sequence cj/buffer-bury-alive-list))) + (unwind-protect + (progn + (should (buffer-live-p buf)) + (cj/kill-buffer-or-bury-alive (buffer-name buf)) + (should-not (buffer-live-p buf))) + (setq cj/buffer-bury-alive-list orig) + (when (buffer-live-p buf) (kill-buffer buf))))) + +(ert-deftest undead-buffers/kill-or-bury-when-in-list-buries () + "cj/kill-buffer-or-bury-alive should bury (not kill) a buffer in the list." + (let* ((name "*dashboard*") ; an element already in the default list + (buf (generate-new-buffer name)) + (orig (copy-sequence cj/buffer-bury-alive-list)) + win-was) + (unwind-protect + (progn + (add-to-list 'cj/buffer-bury-alive-list name) + ;; show it in a temporary window so we can detect bury + (setq win-was (display-buffer buf)) + (cj/kill-buffer-or-bury-alive name) + ;; bury should leave it alive + (should (buffer-live-p buf)) + ;; note: Emacs’s `bury-buffer` does not delete windows by default, + ;; so we no longer assert that no window shows it. + ) + ;; cleanup + (setq cj/buffer-bury-alive-list orig) + (delete-windows-on buf) + (kill-buffer buf)))) + +(ert-deftest undead-buffers/kill-or-bury-adds-to-list-with-prefix () + "Calling `cj/kill-buffer-or-bury-alive' with a prefix arg should add the buffer to the list." + (let* ((buf (generate-new-buffer "test-add-prefix")) + (orig (copy-sequence cj/buffer-bury-alive-list))) + (unwind-protect + (progn + (let ((current-prefix-arg '(4))) + (cj/kill-buffer-or-bury-alive (buffer-name buf))) + (should (member (buffer-name buf) cj/buffer-bury-alive-list))) + (setq cj/buffer-bury-alive-list orig) + (kill-buffer buf)))) + +(ert-deftest undead-buffers/kill-buffer-and-window-removes-window () + "cj/kill-buffer-and-window should delete the current window and kill/bury its buffer." + (let* ((buf (generate-new-buffer "test-kill-and-win")) + (orig (copy-sequence cj/buffer-bury-alive-list))) + (split-window) ; now two windows + (let ((win (next-window))) + (set-window-buffer win buf) + (select-window win) + (cj/kill-buffer-and-window) + (should-not (window-live-p win)) + (unless (member (buffer-name buf) orig) + (should-not (buffer-live-p buf)))) + (setq cj/buffer-bury-alive-list orig))) + +(ert-deftest undead-buffers/kill-other-window-deletes-that-window () + "cj/kill-other-window should delete the *other* window and kill/bury its buffer." + (let* ((buf1 (current-buffer)) + (buf2 (generate-new-buffer "test-other-window")) + (orig (copy-sequence cj/buffer-bury-alive-list))) + (split-window) + (let* ((win1 (selected-window)) + (win2 (next-window win1))) + (set-window-buffer win2 buf2) + ;; stay on the original window + (select-window win1) + (cj/kill-other-window) + (should-not (window-live-p win2)) + (unless (member (buffer-name buf2) orig) + (should-not (buffer-live-p buf2)))) + (setq cj/buffer-bury-alive-list orig))) + +(ert-deftest undead-buffers/kill-all-other-buffers-and-windows-keeps-only-current () + "cj/kill-all-other-buffers-and-windows should delete other windows and kill/bury all other buffers." + (let* ((main (current-buffer)) + (extra (generate-new-buffer "test-all-others")) + (orig (copy-sequence cj/buffer-bury-alive-list))) + (split-window) + (set-window-buffer (next-window) extra) + (cj/kill-all-other-buffers-and-windows) + (should (one-window-p)) + ;; main buffer still exists + (should (buffer-live-p main)) + ;; extra buffer either buried or killed + (unless (member (buffer-name extra) orig) + (should-not (buffer-live-p extra))) + ;; cleanup + (setq cj/buffer-bury-alive-list orig) + (when (buffer-live-p extra) (kill-buffer extra)))) diff --git a/modules/user-constants.el b/modules/user-constants.el index 9c401775..f0fec620 100644 --- a/modules/user-constants.el +++ b/modules/user-constants.el @@ -77,13 +77,7 @@ (defvar article-archive (concat sync-dir "article-archive.org") "The location of the org file that stores saved articples to keep.") - ; -(defvar ledger-file (concat sync-dir "main.ledger") - "The location of the user's ledger file.") - -(defvar macros-file (concat sync-dir "macros.el") - "The location of the macros file for recorded saved macros via M-f3.") - + ; (defvar authinfo-file (concat user-home-dir "/.authinfo.gpg") "The location of the encrypted .authinfo or .netrc file.") @@ -113,9 +107,7 @@ inbox-file contacts-file article-file - article-archive - ledger-file - macros-file)) + article-archive)) (provide 'user-constants) ;;; user-constants.el ends here. |
