diff options
| author | Craig Jennings <c@cjennings.net> | 2024-05-05 09:23:58 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-05-05 09:34:19 -0500 |
| commit | 4566ec69d269ecba8d9386a131b932ee5244aa8e (patch) | |
| tree | fa00edae4ba8c93eee7861fa795052511d4e0f29 | |
| parent | 5f19638abc20eb24511a4129df2be09e1554591c (diff) | |
| download | dotemacs-4566ec69d269ecba8d9386a131b932ee5244aa8e.tar.gz dotemacs-4566ec69d269ecba8d9386a131b932ee5244aa8e.zip | |
enhancements, functions, tests, and misc
enhancements
- move accent-company to C-` and ensure it's on for org mode
- re-enable narrow-to-region
- turn on network repos by default
- remove setq in company's use-package custom clause
- increase company delay to .7 secs
- recipe templates should have visibility show all
- move video recordings code to separate module
- move geiser-guile to prog-lisp
functions
- improve cj/reformat-region-or-buffer via restriction
- improvements to test-format-region
- adding tests for clear-blank-lines
- Add prepend-lines and replace-fraction-glyphs functions
- add cj/clear-blank-lines function
- create cj/load-all-tests utility function
tests
- add keybinding for ert-run-tests-interactively
- ensure ert libraries are available to load-all-tests
- remove running the tests when evaluating the buffer
- fix clear-blank-lines and adding better tests
misc
- updated packages
- adding the luddite blog to elfeed
- more abbrevs
| -rw-r--r-- | .localrepo/archive-contents | 3 | ||||
| -rw-r--r-- | .localrepo/libmpdel-20230816.839.tar | bin | 0 -> 61440 bytes | |||
| -rw-r--r-- | .localrepo/mpdel-20230903.915.tar | bin | 0 -> 51200 bytes | |||
| -rw-r--r-- | .localrepo/navigel-20230903.835.tar | bin | 0 -> 30720 bytes | |||
| -rw-r--r-- | assets/abbrev_defs | 20 | ||||
| -rw-r--r-- | assets/elfeed-feeds.org | 1 | ||||
| -rw-r--r-- | early-init.el | 2 | ||||
| -rw-r--r-- | init.el | 1 | ||||
| -rw-r--r-- | modules/config-utilities.el | 35 | ||||
| -rw-r--r-- | modules/custom-functions.el | 118 | ||||
| -rw-r--r-- | modules/dirvish-config.el | 7 | ||||
| -rw-r--r-- | modules/org-config.el | 1 | ||||
| -rw-r--r-- | modules/org-roam-config.el | 2 | ||||
| -rw-r--r-- | modules/prog-lisp.el | 14 | ||||
| -rw-r--r-- | modules/record-desktop.el | 61 | ||||
| -rw-r--r-- | modules/selection-framework.el | 4 | ||||
| -rw-r--r-- | modules/system-defaults.el | 69 | ||||
| -rw-r--r-- | modules/test-code.el | 63 | ||||
| -rw-r--r-- | modules/text-config.el | 4 | ||||
| -rw-r--r-- | modules/user-constants.el | 7 | ||||
| -rw-r--r-- | tests/test-clear-blank-lines.el | 47 | ||||
| -rw-r--r-- | tests/test-fixup-whitespace.el | 159 | ||||
| -rw-r--r-- | tests/test-format-region.el | 129 | ||||
| -rw-r--r-- | tests/test-title-case-region.el | 44 |
24 files changed, 622 insertions, 169 deletions
diff --git a/.localrepo/archive-contents b/.localrepo/archive-contents index 9dfce7e3c..114f54ee2 100644 --- a/.localrepo/archive-contents +++ b/.localrepo/archive-contents @@ -87,6 +87,7 @@ (kv . [(20140108 1534) nil "key/value data structure functions" tar]) (ledger-mode . [(20240423 445) ((emacs (25 1))) "Helper code for use with the ledger command-line tool" tar]) (leetcode . [(20230524 1851) ((emacs (26 1)) (dash (2 16 0)) (graphql (0 1 1)) (spinner (1 7 3)) (aio (1 0)) (log4e (0 3 3))) "An leetcode client" tar]) + (libmpdel . [(20230816 839) ((emacs (25 1))) "Communication with an MPD server" tar]) (ligature . [(20220808 1225) ((emacs (28))) "Display typographical ligatures in major modes" tar]) (log4e . [(20240123 1313) nil "provide logging framework for elisp" tar]) (lsp-mode . [(20240422 334) ((emacs (27 1)) (dash (2 18 0)) (f (0 20 0)) (ht (2 3)) (spinner (1 7 3)) (markdown-mode (2 3)) (lv (0)) (eldoc (1 11))) "LSP mode" tar]) @@ -100,6 +101,8 @@ (markdown-mode . [(2 6) ((emacs (27 1))) "Major mode for Markdown-formatted text" tar]) (mood-line . [(20231210 1309) ((emacs (26 1))) "A minimal mode line inspired by doom-modeline" tar]) (move-text . [(20231204 1514) nil "Move current line or region with Mdown." tar]) + (mpdel . [(20230903 915) ((emacs (25 1)) (libmpdel (1 2 0)) (navigel (0 7 0))) "Play and control your MPD music" tar]) + (navigel . [(20230903 835) ((emacs (25 1)) (tablist (1 0))) "Facilitate the creation of tabulated-list based UIs" tar]) (nerd-icons . [(20240412 1831) ((emacs (24 3))) "Emacs Nerd Font Icons Library" tar]) (nerd-icons-ibuffer . [(20230417 1549) ((emacs (24 3)) (nerd-icons (0 0 1))) "Display nerd icons in ibuffer" tar]) (nov . [(20240407 1219) ((esxml (0 3 6)) (emacs (25 1))) "Featureful EPUB reader mode" tar]) diff --git a/.localrepo/libmpdel-20230816.839.tar b/.localrepo/libmpdel-20230816.839.tar Binary files differnew file mode 100644 index 000000000..7c6f93cb8 --- /dev/null +++ b/.localrepo/libmpdel-20230816.839.tar diff --git a/.localrepo/mpdel-20230903.915.tar b/.localrepo/mpdel-20230903.915.tar Binary files differnew file mode 100644 index 000000000..061c57586 --- /dev/null +++ b/.localrepo/mpdel-20230903.915.tar diff --git a/.localrepo/navigel-20230903.835.tar b/.localrepo/navigel-20230903.835.tar Binary files differnew file mode 100644 index 000000000..2c9864857 --- /dev/null +++ b/.localrepo/navigel-20230903.835.tar diff --git a/assets/abbrev_defs b/assets/abbrev_defs index 58198bc4b..e6844d2b3 100644 --- a/assets/abbrev_defs +++ b/assets/abbrev_defs @@ -11,6 +11,7 @@ ("accidently" "accidentally" nil :count 0) ("accomodate" "accommodate" nil :count 0) ("accomodating" "accommodating" nil :count 0) + ("accomoplished" "is" nil :count 0) ("acerage" "acreage" nil :count 0) ("acheive" "achieve" nil :count 0) ("acknowlege" "acknowledge" nil :count 0) @@ -27,7 +28,7 @@ ("advizable" "advisable" nil :count 0) ("agression" "aggression" nil :count 0) ("agressive" "aggressive" nil :count 0) - ("ahve" "have" nil :count 1) + ("ahve" "have" nil :count 2) ("aknowledge" "acknowledge" nil :count 0) ("alegiance" "allegiance" nil :count 0) ("allegaince" "allegiance" nil :count 0) @@ -36,7 +37,7 @@ ("amatuer" "amateur" nil :count 0) ("amature" "amateur" nil :count 0) ("annualy" "annually" nil :count 0) - ("anotehr" "another" nil :count 0) + ("anotehr" "another" nil :count 1) ("antoehr" "another" nil :count 0) ("anually" "annually" nil :count 0) ("aparent" "apparent" nil :count 0) @@ -52,6 +53,7 @@ ("availabilty" "availability" nil :count 0) ("balconly" "open" nil :count 0) ("beatiful" "beautiful" nil :count 0) + ("becaue" "because" nil :count 0) ("becuase" "because" nil :count 0) ("begining" "beginning" nil :count 0) ("begnning" "beginning" nil :count 0) @@ -59,6 +61,7 @@ ("benifit" "benefit" nil :count 0) ("beter" "better" nil :count 0) ("betwene" "between" nil :count 0) + ("blamk" "blank" nil :count 0) ("bnot" "should" nil :count 1) ("bookeepping" "bookkeeping" nil :count 0) ("bouy" "buoy" nil :count 0) @@ -102,6 +105,7 @@ ("continute" "continue" nil :count 0) ("contraversy" "controversy" nil :count 0) ("creditscards" "credit cards" nil :count 0) + ("cuases" "causes" nil :count 0) ("customizaton" "customization" nil :count 0) ("dacquiri" "daiquiri" nil :count 0) ("daneel" "Danneel" nil :count 0) @@ -128,6 +132,8 @@ ("embarass" "embarrass" nil :count 0) ("encompasing" "encompassing" nil :count 0) ("endoing" "weeks" nil :count 0) + ("enhamcements" "enhancements" nil :count 0) + ("enumeate" "enumerate" nil :count 0) ("excede" "exceed" nil :count 0) ("exilerate" "exhilarate" nil :count 0) ("existance" "existence" nil :count 0) @@ -142,7 +148,7 @@ ("foriegn" "foreign" nil :count 0) ("francsico" "francisco" nil :count 0) ("freind" "friend" nil :count 0) - ("funciton" "function" nil :count 3) + ("funciton" "function" nil :count 5) ("funcitons" "functions" nil :count 0) ("garantee" "guarantee" nil :count 0) ("garanty" "guarantee" nil :count 0) @@ -221,6 +227,7 @@ ("offboarded" "off" nil :count 0) ("omision" "omission" nil :count 0) ("ommision" "omission" nil :count 0) + ("oppositiion" "the" nil :count 0) ("orignal" "original" nil :count 0) ("ot" "to" nil :count 5) ("otehr" "other" nil :count 2) @@ -255,6 +262,7 @@ ("quesitons" "questions" nil :count 0) ("questionaire" "questionnaire" nil :count 0) ("questionnair" "questionnaire" nil :count 0) + ("quincenera" "quinceañera" nil :count 0) ("readible" "readable" nil :count 0) ("realy" "really" nil :count 0) ("reat" "great" nil :count 0) @@ -280,7 +288,7 @@ ("rythem" "rhythm" nil :count 0) ("rythm" "rhythm" nil :count 0) ("sargent" "sergeant" nil :count 0) - ("scheudle" "schedule" nil :count 0) + ("scheudle" "schedule" nil :count 2) ("secratary" "secretary" nil :count 0) ("secretery" "secretary" nil :count 0) ("seperate" "separate" nil :count 0) @@ -305,7 +313,7 @@ ("takss" "tasks" nil :count 2) ("talekd" "talked" nil :count 0) ("talkign" "talking" nil :count 5) - ("teh" "the" nil :count 62) + ("teh" "the" nil :count 68) ("tehir" "their" nil :count 3) ("tehre" "there" nil :count 2) ("thansk" "thanks" nil :count 2) @@ -320,6 +328,7 @@ ("tyrany" "tyranny" nil :count 0) ("ultimtely" "ultimately" nil :count 0) ("underate" "underrate" nil :count 0) + ("understnading" "understanding" nil :count 0) ("unncessary" "unnecessary" nil :count 0) ("upholstry" "upholstery" nil :count 0) ("usible" "usable" nil :count 0) @@ -333,6 +342,7 @@ ("warant" "warrant" nil :count 0) ("welfair" "welfare" nil :count 0) ("welomce" "welcome" nil :count 0) + ("whenter" "whether" nil :count 0) ("wierd" "weird" nil :count 0) ("withold" "withhold" nil :count 0) ("workign" "working" nil :count 3) diff --git a/assets/elfeed-feeds.org b/assets/elfeed-feeds.org index bf6b2cda7..f9336b9a4 100644 --- a/assets/elfeed-feeds.org +++ b/assets/elfeed-feeds.org @@ -42,6 +42,7 @@ **** [[https://lobste.rs/t/linux.rss][Lobsters Linux]] The Linux Kernel and Its Distributions **** [[https://lobste.rs/t/unix.rss][Lobsters Unix]] *nix ** Blogs :blogs: +*** [[https://theluddite.org/feed.rss][The Luddite]] :tech:blog: *** [[https://blog.aaronbieber.com/posts/index.xml][Aaron Bieber's The Chronicle]] :tech:emacs: *** [[http://dtrace.org/blogs/bmc/feed/][Brian Cantrill's The Observation Deck]] :mustread:tech: *** [[https://drewdevault.com/blog/index.xml][Drew Devault's Blog]] :tech: diff --git a/early-init.el b/early-init.el index 8fe1a67a9..71c94307e 100644 --- a/early-init.el +++ b/early-init.el @@ -56,7 +56,7 @@ ;; --------------------------- Use Online Repos Flag --------------------------- ;; set to nil to only use localrepo and local elpa-mirrors (see script directory) -(defvar cj/use-online-repos nil +(defvar cj/use-online-repos t "Whether to check for network connectivity and use online package repositories.") ;; ---------------------------- Startup Performance ---------------------------- @@ -65,6 +65,7 @@ (require 'markdown-config) (require 'modeline-config) (require 'pdf-config) +(require 'record-desktop) (require 'show-kill-ring) (require 'telegram-config) (require 'tramp-config) diff --git a/modules/config-utilities.el b/modules/config-utilities.el index 3aaa006d8..90268b7d7 100644 --- a/modules/config-utilities.el +++ b/modules/config-utilities.el @@ -6,6 +6,24 @@ ;;; Code: + +;; ------------------------------- Load ERT Tests ------------------------------ + +(defun cj/load-all-tests () + "`load' all ert libraries in test which are not already loaded." + (interactive) + (require 'ert) + (setq ert--tests (make-hash-table :test 'equal)) ;; forget all existing tests + (eval-buffer) + (let ((libraries-loaded (mapcar #'file-name-sans-extension + (delq nil (mapcar #'car load-history)))) + (dir (concat user-emacs-directory "tests/"))) + (dolist (file (directory-files dir t ".+\\.elc?$")) + (let ((library (file-name-sans-extension file))) + (unless (member library libraries-loaded) + (load library nil t) + (push library libraries-loaded)))))) + ;; ------------------------------ Reload Init File ----------------------------- ;; it does what it says it does. @@ -23,13 +41,19 @@ Will recompile natively if supported, or byte-compiled if not." (interactive) (let* ((native-comp-supported (boundp 'native-compile-async)) - (elt-dir (expand-file-name (if native-comp-supported "eln" "elc") user-emacs-directory)) - (message-format (format "Please confirm recursive %s recompilation of %%s: " (if native-comp-supported "native" "byte"))) - (compile-message (format "%scompiling all emacs-lisp files in %%s" (if native-comp-supported "Natively " "Byte-")))) + (elt-dir + (expand-file-name (if native-comp-supported "eln" "elc") + user-emacs-directory)) + (message-format + (format "Please confirm recursive %s recompilation of %%s: " + (if native-comp-supported "native" "byte"))) + (compile-message (format "%scompiling all emacs-lisp files in %%s" + (if native-comp-supported "Natively " "Byte-")))) (if (yes-or-no-p (format message-format user-emacs-directory)) (progn (message "Deleting all compiled files in %s" user-emacs-directory) - (dolist (file (directory-files-recursively user-emacs-directory "\\(\\.elc\\|\\.eln\\)$")) + (dolist (file (directory-files-recursively user-emacs-directory + "\\(\\.elc\\|\\.eln\\)$")) (delete-file file)) (when (file-directory-p elt-dir) (delete-directory elt-dir t t)) @@ -46,7 +70,8 @@ Will recompile natively if supported, or byte-compiled if not." (defun cj/delete-emacs-home-compiled-files () "Delete all compiled files recursively in \='user-emacs-directory\='." (interactive) - (message "Deleting compiled files under %s. This may take a while." user-emacs-directory) + (message "Deleting compiled files under %s. This may take a while." + user-emacs-directory) (require 'find-lisp) ;; make sure the package is required (mapc (lambda (path) (when (or (string-suffix-p ".elc" path) diff --git a/modules/custom-functions.el b/modules/custom-functions.el index 68c2270f2..4f9c784b6 100644 --- a/modules/custom-functions.el +++ b/modules/custom-functions.el @@ -25,7 +25,7 @@ (t (message "Cursor doesn't follow parenthesis, so there's no match.")))) ;; ---------------------------- Join Line Or Region ---------------------------- -;; joins all selected lines and fixes up the whitespace. +;; joins all selected lines and fixes up the whitespace. (defun cj/join-line-or-region (beg end) "Apply \='join-line\=' over the marked region or join with previous line. @@ -112,22 +112,16 @@ If no region is selected, operate on the whole buffer." ;; reindent, untabify, and delete trailing whitespace across region or buffer (defun cj/format-region-or-buffer () - "Reformat the region or the entire buffer. -If a region is selected, delete trailing whitespace, then indent and untabify -the region. If no region is selected, perform the same actions across the -buffer." + "Reformat the region or the entire buffer." (interactive) - (let (start-pos end-pos) - (if (use-region-p) - (progn - (setq start-pos (region-beginning)) - (setq end-pos (region-end))) - (setq start-pos (point-min)) - (setq end-pos (point-max))) - (save-excursion - (delete-trailing-whitespace start-pos end-pos) - (indent-region start-pos end-pos nil) - (untabify start-pos end-pos)))) + (let ((start-pos (if (use-region-p) (region-beginning) (point-min))) + (end-pos (if (use-region-p) (region-end) (point-max)))) + (save-excursion + (save-restriction + (narrow-to-region start-pos end-pos) + (delete-trailing-whitespace) + (indent-region (point-min) (point-max)) + (untabify (point-min) (point-max)))))) ;; ------------------- Remove Leading And Trailing Whitespace ------------------ ;; removes leading and trailing whitespace on line, region, or buffer. @@ -263,6 +257,7 @@ User is prompted for the optional descriptor." (message "Can't insert around. No word at point and no region selected.")))))) (global-set-key (kbd "C-; i a") 'cj/insert-around-word-or-region) + ;; ------------------------ Insert Around Word Or Region ----------------------- (defun cj/insert-around-word-or-region () @@ -305,6 +300,26 @@ User is prompted for the optional descriptor." (insert str) (forward-line 1))))) +;; -------------------- Prepend To Lines In Region Or Buffer -------------------- +;; prepend characters to the beginning of all lines in the region or the buffer. +;; should probably be collapsed into the append lines function. . + +(defun cj/prepend-to-lines-in-region-or-buffer (str) + "Prompt for STR and prepend it to the start of each line in region or buffer." + (interactive "sEnter string to prepend: ") + (let ((start-pos (if (use-region-p) + (region-beginning) + (point-min))) + (end-pos (if (use-region-p) + (region-end) + (point-max)))) + (save-excursion + (goto-char start-pos) + (while (< (point) end-pos) + (beginning-of-line 1) + (insert str) + (forward-line 1))))) + ;; ------------------------------ Hyphenate Region ----------------------------- ;; hyphenates any empty space in a region; complains if there's no Region @@ -385,7 +400,8 @@ and all articles are considered minor words." ;; Check the beginning of the previous word doesn't reset first. (save-excursion (and - (not (zerop (skip-chars-backward "[:blank:]" prev-word-end))) + (not (zerop + (skip-chars-backward "[:blank:]" prev-word-end))) (memq (char-before (point)) chars-skip-reset)))) (delete-region (point) (1+ (point))) (insert c-up)))))) @@ -397,14 +413,68 @@ and all articles are considered minor words." ;; --------------------------- Buffer Strip Control M -------------------------- ;; remove windows carriage return control characters from the buffer -(defun buffer-strip-ctrl-m () +(defun cj/buffer-strip-ctrl-m () "Remove ^M from the current buffer." (interactive) (save-excursion (goto-char (point-min)) - (while (search-forward "^M" nil t) + (while (search-forward "" nil t) (replace-match "" nil t)))) +;; ----------------------------- Clear Blank Lines ----------------------------- + +(defun cj/clear-blank-lines (beginning end) + "Remove blank lines in the region or the buffer if no region is selected. +BEGINNING and END describe the selected region." + (interactive "r") + (save-excursion + (goto-char beginning) + (while (re-search-forward "^[ \t]*\n" end t) + (replace-match "")))) + +;; ---------------------- Fixup Whitespace Line Or Region ---------------------- + +(defun cj/fixup-whitespace-line-or-region (&optional region) + "Fix up whitespace in the current line, or region if selected. +Ensure there is exactly one space between words, and remove leading and trailing +whitespace. When called with a prefix argument, it operates on the current +REGION." + (interactive "P") + (save-excursion + (let* ((beg (if region (region-beginning) (line-beginning-position))) + (end (if region (region-end) (line-end-position)))) + (save-restriction + (narrow-to-region beg end) + ;; Replace all tabs with space + (goto-char (point-min)) + (replace-string "\t" " " nil beg end) + ;; Remove leading and trailing spaces + (goto-char (point-min)) + (while (re-search-forward "^\\s-+\\|\\s-+$" nil t) + (replace-match "" nil nil)) + ;; Ensure only one space between words/symbols. + (goto-char (point-min)) + (while (re-search-forward "\\s-\\{2,\\}" nil t) + (replace-match " " nil nil)))))) + +;; -------------------------- Replace Fraction Glyphs -------------------------- + +(defun cj/replace-fraction-glyphs (start end) + "Replace common fraction glyphs with their spelled out format. +Operates in the buffer or region (as identified with START and END) if selected. +Replaces the text with the glyphs if called with C-u." + (interactive "r") + (let ((replacements (if current-prefix-arg + '(("1/4" . "¼") ("1/2" . "½") ("3/4" . "¾") + ("1/3" . "⅓") ("2/3" . "⅔")) + '(("¼" . "1/4") ("½" . "1/2") ("¾" . "3/4") + ("⅓" . "1/3") ("⅔" . "2/3"))))) + (save-excursion + (dolist (r replacements) + (goto-char start) + (while (search-forward (car r) end t) + (replace-match (cdr r))))))) + ;; ------------------------------ Insert Date Time ----------------------------- ;; insert a sortable or a readable datestamp or timestamp @@ -557,11 +627,12 @@ Uses `sortable-time-format' for the formatting the date/time." (define-key map "d" 'cj/duplicate-line-or-region) (define-key map "D" 'cj/remove-duplicate-lines-from-region-or-buffer) - (define-key map ")" #'cj/jump-to-matching-paren) + (define-key map ")" #'cj/jump-to-matching-paren) + (define-key map "/" #'cj/replace-fraction-glyphs) + (define-key map "L" #'cj/clear-blank-lines) (define-key map "-" #'cj/hyphenate-region) (define-key map "U" 'upcase-region) - (define-key map "w" 'cj/remove-leading-trailing-whitespace) - (define-key map "W" 'fixup-whitespace) + (define-key map "w" 'cj/fixup-whitespace-line-or-region) (define-key map "#" 'cj/count-words-buffer-or-region) (define-key map "1" 'cj/alphabetize-and-replace-region) (define-key map "C" 'display-fill-column-indicator-mode) @@ -570,6 +641,7 @@ Uses `sortable-time-format' for the formatting the date/time." (define-key map "j" 'cj/join-line-or-region) (define-key map "l" 'downcase-dwim) (define-key map "p" 'cj/append-to-lines-in-region-or-buffer) + (define-key map "P" 'cj/prepend-to-lines-in-region-or-buffer) (define-key map "r" 'align-regexp) (define-key map "u" 'cj/title-case-region) (define-key map "c" 'cj/wrap-region-as-code-span) @@ -583,7 +655,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/rename-buffer-and-file) +(global-set-key (kbd "C-; b r") 'cj/renameq-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/dirvish-config.el b/modules/dirvish-config.el index d5dc6c33a..c0cf7309c 100644 --- a/modules/dirvish-config.el +++ b/modules/dirvish-config.el @@ -99,16 +99,17 @@ automatically displayed." ("cx" ,code-dir "code diredtory") ("ws" ,(concat code-dir "/website") "website staging") ("dr" ,(concat sync-dir "/drill/") "drill files") - ("s" ,sync-dir "sync directory") - ("mp" ,(concat sync-dir "/playlists") "music playlists") + ("s" ,sync-dir "sync directory") + ("vr" ,video-recordings-dir "video recordings directory") ("px" ,projects-dir "projects directory") ("tg" ,(concat sync-dir "/text.games") "text games") ("ps" ,(concat pix-dir "/screenshots/") "pictures screenshots") ("pw" ,(concat pix-dir "/wallpaper/") "pictures wallpaper") ("px" ,pix-dir "pictures directory") ("dl" ,dl-dir "downloads") - ("dt" ,(concat dl-dir "/torrents/complete/") "torrents") + ("dt" ,(concat dl-dir "/torrents/complete/") "torrents") ("vx" ,videos-dir "videos") + ("pl" "~/sync/playlists/" "playlists directory") ("df" "~/.dotfiles/" "dotfiles") ("dx" "~/documents/" "documents") ("mx" "~/music/" "music") diff --git a/modules/org-config.el b/modules/org-config.el index ac206d093..d7230381a 100644 --- a/modules/org-config.el +++ b/modules/org-config.el @@ -204,7 +204,6 @@ org-archive-subtree-default are placed.") (org-mode . flyspell-mode) (org-mode . turn-on-visual-line-mode) (org-mode . org-indent-mode) - (org-mode . (lambda () (interactive) (company-mode -1))) ;; no company-mode in org :config (cj/org-general-settings) diff --git a/modules/org-roam-config.el b/modules/org-roam-config.el index ede2025f9..e7d7b980f 100644 --- a/modules/org-roam-config.el +++ b/modules/org-roam-config.el @@ -30,7 +30,7 @@ ("r" "recipe" plain (function (lambda () (concat roam-dir "templates/recipe.org"))) :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title} - #+CATEGORY: ${title}\n#+FILETAGS: Recipe") + #+CATEGORY: ${title}\n#+FILETAGS: Recipe\n#+STARTUP: showall") :unnarrowed t) ("p" "project" plain (function (lambda () (concat roam-dir "templates/project.org"))) diff --git a/modules/prog-lisp.el b/modules/prog-lisp.el index 59eb122b8..c68e04cfa 100644 --- a/modules/prog-lisp.el +++ b/modules/prog-lisp.el @@ -80,8 +80,11 @@ (ert t)) (keymap-global-unset "C-r" t) + (keymap-global-unset "C-R" t) (define-key emacs-lisp-mode-map (kbd "C-r") 'ert-all-tests) - (define-key lisp-interaction-mode-map (kbd "C-r") 'ert-all-tests)) + (define-key emacs-lisp-mode-map (kbd "C-R") 'ert-run-tests-interactively) + (define-key lisp-interaction-mode-map (kbd "C-r") 'ert-all-tests) + (define-key lisp-interaction-mode-map (kbd "C-R") 'ert-run-tests-interactively)) (use-package el-mock) ;; mock/stub framework @@ -125,6 +128,15 @@ (set-face-foreground 'rainbow-delimiters-depth-8-face "#999") ;; medium gray (set-face-foreground 'rainbow-delimiters-depth-9-face "#666")) ;; dark gray +;; -------------------------------- Geiser Guile ------------------------------- +;; Guile support in Emacs + +(use-package geiser-guile + :defer 1 + :commands (geiser-guile) + :bind ("C-c G" . geiser-guile) + :config + (setq geiser-guile-binary "/usr/bin/guile")) (provide 'prog-lisp) ;;; prog-lisp.el ends here diff --git a/modules/record-desktop.el b/modules/record-desktop.el new file mode 100644 index 000000000..6c5a4fac9 --- /dev/null +++ b/modules/record-desktop.el @@ -0,0 +1,61 @@ +;;; record-desktop.el --- Video Record desktop -*- lexical-binding: t; -*- + +;;; Commentary: +;; Use ffmpeg to video record your desktop. +;; with audio from mic and audio from default audio sink + +;; Note: video-recordings-dir is defined (and directory created) in +;; user-cosntants.el + +;;; Code: + +(defvar cj/video-recording-ffmpeg-process nil + "Variable to store the process of the ffmpeg recording.") + +(defun cj/video-recording-start (arg) + "Starts the ffmpeg recording. +If called with a prefix arg C-u, choose the location on where to save the +recording, otherwise use the default location in `video-recordings-dir'." + (interactive "P") + (let* ((location (if arg + (read-directory-name "Enter recording location: ") + video-recordings-dir)) + (directory (file-name-directory location))) + (unless (file-directory-p directory) + (make-directory directory t)) + (cj/ffmpeg-record location))) + +(defun cj/ffmpeg-record (directory) + "Start an ffmpeg recording. Save output to DIRECTORY." + (unless cj/video-recording-ffmpeg-process + (let* ((location (expand-file-name directory)) + (name (format-time-string "%Y-%m-%d-%H-%M-%S")) + (filename (concat location "/" name ".mkv")) + (ffmpeg-command + (concat "ffmpeg -framerate 30 -f x11grab -i :0.0+ " + "-f pulse -i " + "alsa_input.pci-0000_00_1b.0.analog-stereo " + "-ac 1 " + "-f pulse -i " + "alsa_output.pci-0000_00_1b.0.analog-stereo.monitor " + "-ac 2 " filename))) + ;; start the recording + (setq cj/video-recording-ffmpeg-process + (start-process-shell-command "ffmpeg-recording" + "*ffmpeg-recording*" + ffmpeg-command)) + (set-process-query-on-exit-flag cj/video-recording-ffmpeg-process nil) + (message "Started recording process.")))) + +(defun cj/video-recording-stop () + "Stop the ffmpeg recording process." + (interactive) + (when cj/video-recording-ffmpeg-process + (delete-process cj/video-recording-ffmpeg-process) + (setq cj/video-recording-ffmpeg-process nil) + (message "Stopped video recording."))) + + + +(provide 'record-desktop) +;;; record-desktop.el ends here. diff --git a/modules/selection-framework.el b/modules/selection-framework.el index 6428a9771..1ee83ca22 100644 --- a/modules/selection-framework.el +++ b/modules/selection-framework.el @@ -28,9 +28,9 @@ ;; provide proper casing even if I don't. (company-dabbrev-ignore-case t) ;; company completion wait - (company-idle-delay 0.2) + ( company-idle-delay 0.7) ;; use vscode icons in the margin - (setq company-format-margin-function #'company-vscode-light-icons-margin) + (company-format-margin-function #'company-vscode-light-icons-margin) ;; no company-mode in shell & eshell (company-global-modes '(not eshell-mode shell-mode))) diff --git a/modules/system-defaults.el b/modules/system-defaults.el index 48ac3d502..b7af439b2 100644 --- a/modules/system-defaults.el +++ b/modules/system-defaults.el @@ -42,26 +42,27 @@ ;; ------------------------- Re-Enabling Functionality ------------------------- +(put 'narrow-to-region 'disabled nil) ;; narrow-to-region is extremely useful! (put 'upcase-region 'disabled nil) ;; upcase region is useful (put 'erase-buffer 'disabled nil) ;; and so is erase-buffer ;; ------------------------------ Non UI Settings ------------------------------ -(setq ring-bell-function 'ignore) ;; disable the bell ring. -(setq default-directory user-home-dir) ;; consider user home the default directory +(setq ring-bell-function 'ignore) ;; disable the bell ring. +(setq default-directory user-home-dir) ;; consider user home the default directory -(global-auto-revert-mode) ;; update the buffer when the associated file has changed -(setq global-auto-revert-non-file-buffers t) ;; do so for all buffer types (e.g., ibuffer) -(setq bidi-display-reordering nil) ;; don't reorder bidirectional text for display -(setq bidi-paragraph-direction t) ;; forces directionality of text for performance. +(global-auto-revert-mode) ;; update the buffer when the associated file has changed +(setq global-auto-revert-non-file-buffers t) ;; do so for all buffer types (e.g., ibuffer) +(setq bidi-display-reordering nil) ;; don't reorder bidirectional text for display +(setq bidi-paragraph-direction t) ;; forces directionality of text for performance. -(setq system-time-locale "C") ;; use en_US locale to format time. +(setq system-time-locale "C") ;; use en_US locale to format time. ;; --------------------------------- Clipboard --------------------------------- -(setq select-enable-clipboard t) ;; cut and paste using clipboard -(setq yank-pop-change-selection t) ;; update system clipboard when yanking in emacs -(setq save-interprogram-paste-before-kill t) ;; saves existing clipboard to kill ring before replacing +(setq select-enable-clipboard t) ;; cut and paste using clipboard +(setq yank-pop-change-selection t) ;; update system clipboard when yanking in emacs +(setq save-interprogram-paste-before-kill t) ;; saves existing clipboard to kill ring before replacing ;; -------------------------------- Tab Settings ------------------------------- ;; use spaces, not tabs @@ -77,9 +78,9 @@ ;; ----------------------------- Case Insensitivity ---------------------------- ;; make user interfaces case insensitive -(setq case-fold-search t) ;; case-insensitive searches -(setq completion-ignore-case t) ;; case-insensitive completion -(setq read-file-name-completion-ignore-case t) ;; case-insensitive file completion +(setq case-fold-search t) ;; case-insensitive searches +(setq completion-ignore-case t) ;; case-insensitive completion +(setq read-file-name-completion-ignore-case t) ;; case-insensitive file completion ;; ------------------------------- Async Commands ------------------------------ ;; always create new async command buffers silently @@ -94,9 +95,9 @@ ;; ------------------------ Mouse And Trackpad Settings ------------------------ ;; provide smoothest scrolling and avoid accidental gestures -(setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse -(setq scroll-margin 5) ;; scroll w/in 10 lines of top/bottom -(setq scroll-step 1) ;; keyboard scroll one line at a time +(setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse +(setq scroll-margin 5) ;; scroll w/in 10 lines of top/bottom +(setq scroll-step 1) ;; keyboard scroll one line at a time ;; disable pasting with mouse-wheel click (global-unset-key (kbd "<mouse-2>")) @@ -108,19 +109,19 @@ ;; ------------------------------- Be Quiet(er)! ------------------------------- ;; reduces "helpful" instructions that distract Emacs power users. -(setq-default vc-follow-symlinks) ;; don't ask to follow symlinks if target is version controlled -(setq kill-buffer-query-functions ;; don't ask about killing buffers with processes, just kill them +(setq-default vc-follow-symlinks) ;; don't ask to follow symlinks if target is version controlled +(setq kill-buffer-query-functions ;; don't ask about killing buffers with processes, just kill them (remq 'process-kill-buffer-query-function kill-buffer-query-functions)) -(setq confirm-kill-processes nil) ;; automatically kill running processes on exit -(setq confirm-nonexistent-file-or-buffer nil) ;; don't ask if a file I visit with C-x C-f or C-x b doesn't exist -(setq ad-redefinition-action 'accept) ;; silence warnings about advised functions getting redefined. -(setq large-file-warning-threshold nil) ;; open files regardless of size -(fset 'yes-or-no-p 'y-or-n-p) ;; require a single letter for binary answers -(setq use-short-answers t) ;; same as above with Emacs 28+ -(setq auto-revert-verbose nil) ;; turn off auto revert messages -(setq custom-safe-themes t) ;; treat all themes as safe (stop asking) -(setq server-client-instructions nil) ;; I already know what to do when done with the frame +(setq confirm-kill-processes nil) ;; automatically kill running processes on exit +(setq confirm-nonexistent-file-or-buffer nil) ;; don't ask if a file I visit with C-x C-f or C-x b doesn't exist +(setq ad-redefinition-action 'accept) ;; silence warnings about advised functions getting redefined. +(setq large-file-warning-threshold nil) ;; open files regardless of size +(fset 'yes-or-no-p 'y-or-n-p) ;; require a single letter for binary answers +(setq use-short-answers t) ;; same as above with Emacs 28+ +(setq auto-revert-verbose nil) ;; turn off auto revert messages +(setq custom-safe-themes t) ;; treat all themes as safe (stop asking) +(setq server-client-instructions nil) ;; I already know what to do when done with the frame ;; ------------------ Reduce Garbage Collections In Minibuffer ----------------- ;; triggers garbage collection when it won't impact user minibuffer entries @@ -174,13 +175,13 @@ (make-directory cj/backup-directory t)) ;; BACKUP SETTINGS -(setq make-backup-files t) ;; do make backup files -(setq backup-directory-alist `(("." . ,cj/backup-directory))) ;; put all originals in backup directory -(setq backup-by-copying t) ;; don't clobber symlinks -(setq version-control t) ;; make numeric backup versions -(setq delete-old-versions t) ;; delete excess backup files w/o asking -(setq kept-new-versions 25) ;; keep 25 of the newest backups made (default: 2) -(setq vc-make-backup-files t) ;; also backup any files in version control +(setq make-backup-files t) ;; do make backup files +(setq backup-directory-alist `(("." . ,cj/backup-directory))) ;; put all originals in backup directory +(setq backup-by-copying t) ;; don't clobber symlinks +(setq version-control t) ;; make numeric backup versions +(setq delete-old-versions t) ;; delete excess backup files w/o asking +(setq kept-new-versions 25) ;; keep 25 of the newest backups made (default: 2) +(setq vc-make-backup-files t) ;; also backup any files in version control ;; ---------------------------- Exec Path From Shell --------------------------- ;; ensure $PATH is the same between your normal shell and your Emacs shells. diff --git a/modules/test-code.el b/modules/test-code.el index 409f8e079..bde37cb20 100644 --- a/modules/test-code.el +++ b/modules/test-code.el @@ -7,15 +7,14 @@ ;;; Code: -;; -------------------------------- Geiser Guile ------------------------------- -;; Guile support in Emacs +;; ----------------------------------- Mpdel ----------------------------------- -(use-package geiser-guile - :defer 1 - :commands (geiser-guile) - :bind ("C-c G" . geiser-guile) +(use-package mpdel + :defer .5 :config - (setq geiser-guile-binary "/usr/bin/guile")) + (setq mpdel-prefix-key (kbd "M-p")) + (mpdel-mode)) + ;; ---------------------------------- Yeetube ---------------------------------- ;; youtube frontend for emacs @@ -56,56 +55,6 @@ :config (easy-hugo-enable-menu)) - -;; --------------------------------- Recording --------------------------------- - -(defvar cj/ffmpeg-process nil - "Variable to store the process of the ffmpeg recording.") - -(defvar cj/recording-location "~/videos/recordings" - "The location to save the ffmpeg recordings.") - -(defun cj/start-recording (arg) - "Starts the ffmpeg recording. -If called with a prefix arg C-u, choose the location on where to save the recording, -otherwise use the default location in `cj/recording-location'." - (interactive "P") - (let* ((location (if arg - (read-directory-name "Enter recording location: ") - cj/recording-location)) - (directory (file-name-directory location))) - (unless (file-directory-p directory) - (make-directory directory t)) - (cj/ffmpeg-record location))) - -(defun cj/ffmpeg-record (directory) - "Start an ffmpeg recording. Save output to DIRECTORY." - (unless cj/ffmpeg-process - (let* ((location (expand-file-name directory)) - (name (format-time-string "%Y-%m-%d-%H-%M-%S")) - (filename (concat location "/" name ".mkv")) - (ffmpeg-command - (concat "ffmpeg -framerate 30 -f x11grab -i :0.0+ " - "-f pulse -i alsa_input.pci-0000_00_1b.0.analog-stereo " - "-ac 1 -f pulse -i alsa_output.pci-0000_00_1b.0.analog-stereo.monitor " - "-ac 2 " filename))) - ;; start the recording - (setq cj/ffmpeg-process - (start-process-shell-command "ffmpeg-recording" - "*ffmpeg-recording*" - ffmpeg-command)) - (set-process-query-on-exit-flag cj/ffmpeg-process nil) - (message "Started recording process.")))) - -(defun cj/stop-recording () - "Stop the ffmpeg recording process." - (interactive) - (when cj/ffmpeg-process - (delete-process cj/ffmpeg-process) - (setq cj/ffmpeg-process nil) - (message "Stopped recording process."))) - - ;; -------------------------------- Google This -------------------------------- (use-package google-this diff --git a/modules/text-config.el b/modules/text-config.el index 9db626ed8..e3713fefb 100644 --- a/modules/text-config.el +++ b/modules/text-config.el @@ -94,12 +94,12 @@ :config (setq-default olivetti-body-width 100)) -;; --------------------------- Acccent (Diacriticals) -------------------------- +;; --------------------------- Accent (Diacriticals) --------------------------- ;; an easy way to enter diacritical marks (use-package accent :defer 1 - :bind ("C-c C-a" . accent-company)) + :bind ("C-`" . accent-company)) ;; ----------------------------- Visual Fill Column ---------------------------- ;; text wrapping diff --git a/modules/user-constants.el b/modules/user-constants.el index 56c0f2f91..11872474a 100644 --- a/modules/user-constants.el +++ b/modules/user-constants.el @@ -55,6 +55,10 @@ (defconst snippets-dir (concat sync-dir "snippets/") "The location of ya-snippet snippets.") +(defconst video-recordings-dir "~/videos/recordings" + "The location to save the ffmpeg recordings.") + + ;; FILES (defvar schedule-file (concat sync-dir "schedule.org") "The location of the org file containing scheduled events.") @@ -99,7 +103,8 @@ (mapc 'cj/verify-or-create-dir (list sync-dir roam-dir journals-dir - snippets-dir)) + video-recordings-dir + snippets-dir)) (mapc 'cj/verify-or-create-file (list schedule-file inbox-file diff --git a/tests/test-clear-blank-lines.el b/tests/test-clear-blank-lines.el new file mode 100644 index 000000000..2190aba00 --- /dev/null +++ b/tests/test-clear-blank-lines.el @@ -0,0 +1,47 @@ +;;; test-clear-blank-lines.el --- -*- lexical-binding: t; -*- + +;;; Commentary: +;; + +;;; Code: + +(require 'ert) +(add-to-list 'load-path (concat user-emacs-directory "modules")) +(require 'custom-functions) + +(ert-deftest test-cj/clear-blank-lines-region () + (let ((testdata "Some\n\n\n\nText") + (expected "Some\nText") + (actual)) + (with-temp-buffer + (insert testdata) + (cj/clear-blank-lines (point-min) (point-max)) + (setq actual (buffer-string)) + (message "buffer is:\n'%s'" actual) + (should (string= actual expected))))) + +(ert-deftest test-cj/clear-blank-lines-region-multiple-lines () + (let ((testdata "Some\n\n\n\nText") + (expected "Some\n\n\n\nText") + (midpoint) + (actual)) + (with-temp-buffer + (insert testdata) + (insert "\n") + (setq midpoint (point)) + (insert testdata) + (cj/clear-blank-lines (point-min) midpoint) + (setq actual (buffer-substring (- (point-max) + (length testdata)) (point-max))) + (message "buffer is:\n'%s'" (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/clear-blank-lines-negative () + (with-temp-buffer + (insert "Some\nText") + (cj/clear-blank-lines (point-min) (point-max)) + (should (equal (buffer-string) "Some\nText")))) + + +(provide 'test-clear-blank-lines) +;;; test-clear-blank-lines.el ends here. diff --git a/tests/test-fixup-whitespace.el b/tests/test-fixup-whitespace.el new file mode 100644 index 000000000..0126801ad --- /dev/null +++ b/tests/test-fixup-whitespace.el @@ -0,0 +1,159 @@ +;;; test-fixup-whitespace.el --- -*- lexical-binding: t; -*- + +;;; Commentary: +;; Test cj/fixup-whitespace-line-or-region in custom-functions.el + +;; The function under test should: +;; - ensure there is exactly one space between words +;; - remove tab characters +;; - remove leading and trailing whitespace +;; - operate on a line, or a region, if selected + +;;; Code: + + +(require 'ert) +(add-to-list 'load-path (concat user-emacs-directory "modules")) +(require 'custom-functions) + +(ert-deftest test-cj/fixup-whitespace-positive-first-line-only () + "Test a positive case with two lines. +Both lines have whitespace at the beginning and the end. This tests that when +this function is called on the first line, only that line is affected." + (let ((testdata " Hello, world! \n Foo bar ") + (expected "Hello, world!\n Foo bar ") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-positive-first-line-only-tabs () + "Test a positive case with two lines. +Both lines have extraneous whitespace at the beginning and the end, includuing +tabs. This tests that when this function is called on the first line, only that +line is affected." + (let ((testdata " Hello,\t world! \n Foo\tbar ") + (expected "Hello, world!\n Foo\tbar ") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-positive-first-line-only-tabs2 () + "Test a positive case with two lines. +Both lines have extraneous whitespace at the beginning and the end, includuing +tabs. This tests that when this function is called on the first line, only that +line is affected." + (let ((testdata "\t Hello,\tworld! \n Foo\t bar\t ") + (expected "Hello, world!\n Foo\t bar\t ") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-negative-first-line-only () + "Test a negative case with two lines. +Only the second line has whitespace at the beginning and the end. This tests +that when this function is called on the first line, neither line changes." + (let ((testdata "Hello, world!\n Foo bar ") + (expected "Hello, world!\n Foo bar ") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-positive-second-line-only () + "Test a positive case with two lines. +Both lines have whitespace at the beginning and the end. This tests that when +function is called on the second line, only that line is affected." + (let ((testdata " Hello, world! \n Foo bar ") + (expected " Hello, world! \nFoo bar") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (forward-line) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-negative-second-line-only () + "Test a negative case with two lines. +Only the first line has whitespace at the beginning and the end. This tests +that when this function is called on the first line, neither line changes." + (let ((testdata " Hello, world! \nFoo bar") + (expected " Hello, world! \nFoo bar") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (forward-line) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-positive-region () + "Test a positive case with a region. +Two lines have whitespace at the beginning, the middle, and the end. This tests +that when this function is called with a region, all whitespace is cleaned up as +expected." + (let ((testdata " Hello, world! \n Foo bar ") + (expected "Hello, world!\nFoo bar") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (set-mark (point)) + (goto-char (point-max)) + (cj/fixup-whitespace-line-or-region t) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-positive-region-tabs () + "Test a positive case with a region and tabs. +Two lines have extraneous whitespace at the beginning, the middle, and the end. +This tests that when this function is called with a region, all whitespace is +cleaned up as expected." + (let ((testdata " \t \t Hello, world! \n Foo\t bar ") + (expected "Hello, world!\nFoo bar") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (set-mark (point)) + (goto-char (point-max)) + (cj/fixup-whitespace-line-or-region t) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(ert-deftest test-cj/fixup-whitespace-negative-region () + "Test a negative case with a region. +Two lines are inserted, neither of which have extraneous whitespace. This tests +that when this function is called with a region, there's no unwanted +side-effects and nothing changes." + (let ((testdata "Hello, world!\nFoo bar") + (expected "Hello, world!\nFoo bar") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (set-mark (point)) + (goto-char (point-max)) + (cj/fixup-whitespace-line-or-region t) + (setq actual (buffer-string)) + (should (string= actual expected))))) + +(provide 'test-fixup-whitespace) +;;; test-fixup-whitespace.el ends here. diff --git a/tests/test-format-region.el b/tests/test-format-region.el index b1d1532c7..25d2e52e8 100644 --- a/tests/test-format-region.el +++ b/tests/test-format-region.el @@ -1,47 +1,110 @@ -;;; test-format-region.el --- tests for cj/format-region-or-buffer -*- lexical-binding: t; -*- +;;; test-format-region.el --- -*- lexical-binding: t; -*- ;;; Commentary: -;; Some basic tests for the custom function cj/format-region-or-buffer in custom-functions.el +;; Some basic tests for the custom function cj/format-region-or-buffer in +;; custom-functions.el ;;; Code: (add-to-list 'load-path (concat user-emacs-directory "modules")) (require 'custom-functions) -;; ----------------------------- Utility Functions ----------------------------- - -(defun buffer-string-no-properties () - "Return the contents of the current buffer without any text properties." - (buffer-substring-no-properties (point-min) (point-max))) ;; ----------------------------------- Tests ----------------------------------- -(ert-deftest cj/format-region-or-buffer-test/region () - "Test cj/format-region-or-buffer on a selected region." - (with-temp-buffer - (insert " line with leading spaces and a \n tab\there") - (goto-char (point-min)) - (push-mark (point) t t) - (goto-char (point-max)) - (cj/format-region-or-buffer) - ;; expected: trailing whitespace and leading spaces are removed, tabs are replaced by spaces - (should (string= (buffer-string-no-properties) "line with leading spaces and a\ntab here")))) - -(ert-deftest cj/format-region-or-buffer-test/whole-buffer () - "Test cj/format-region-or-buffer on an entire buffer." - (with-temp-buffer - (insert " \n\t\n line with leading spaces and a \n tab\there") - ;; expected: trailing and leading whitespace of buffer and lines are removed, tabs are replaced by spaces - (cj/format-region-or-buffer) - (should (string= (buffer-string-no-properties) "\nline with leading spaces and a\ntab here")))) - -(ert-deftest cj/format-region-or-buffer-test/extreme-buffer-size () - "Tests cj/format-region-or-buffer on an very large buffer." - (with-temp-buffer - (insert (make-string most-positive-fixnum ?\s)) - (cj/format-region-or-buffer) - ;; expected: even large buffers should not cause an error - (should (string= (buffer-string-no-properties) "")))) +(defvar test-format-rob-text-data + '((" spaces in front\nspaces behind " . + "spaces in front\nspaces behind") + ("\t tabs and spaces in front\ntabs and spaces behind\t " . + "tabs and spaces in front\ntabs and spaces behind"))) + +(defvar test-format-rob-elisp-data + '(("(defun existential ()\n(if (eq (+ 3 4) 7)\n(order)\n(chaos)))" . + "(defun existential ()\n (if (eq (+ 3 4) 7)\n (order)\n (chaos)))"))) + + +(ert-deftest test-format-rob-positive-text-region () + "Test cj/format-region-or-buffer on a selected region. +This tests " + (dolist (data-pair test-format-rob-text-data) + (let* ((testdata (car data-pair)) + (expected (cdr data-pair)) + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (set-mark (point)) + (goto-char (point-max)) + (cj/format-region-or-buffer) + (setq actual (buffer-string)) + (should (string= actual expected)))))) + +(ert-deftest test-format-rob-positive-text-buffer () + "Test cj/format-region-or-buffer on the entire buffer. +This is the same as testing the region without setting a region in the temp +buffer." + (dolist (data-pair test-format-rob-text-data) + (let* ((testdata (car data-pair)) + (expected (cdr data-pair)) + (actual)) + (with-temp-buffer + (insert testdata) + (cj/format-region-or-buffer) + (setq actual (buffer-string)) + (should (string= actual expected)))))) + +(ert-deftest test-format-rob-positive-region-text-multiple-paragraphs () + "Test cj/format-region-or-buffer on the entire buffer." + (dolist (data-pair test-format-rob-text-data) + (let ((testdata (car data-pair)) + (expected1 (cdr data-pair)) + (expected2 (car data-pair)) + (actual1) + (actual2)) + (with-temp-buffer + ;; insert data twice with newline char in between + (insert testdata) + (insert"\n") + (insert testdata) + + ;; select the first set of data + (goto-char (point-min)) + (set-mark (point)) + (forward-line 2) + + ;; run format and return to top + (cj/format-region-or-buffer) + (message "buffer is:\n'%s'" (buffer-string)) + + ;; assert the first set is formatted + (goto-char (point-min)) + (setq actual1 (buffer-substring (point-min) (line-end-position 2))) + (should (string= actual1 expected1)) + + ;; assert the second set is unformatted + (goto-char (point-min)) + (setq actual2 (buffer-substring (line-beginning-position 3) (point-max))) + (should (string= actual2 expected2)))))) + +(ert-deftest test-format-rob-positive-elisp-region () + "Test cj/format-region-or-buffer on a selected region. +This tests that emacs-lisp specific formatting is applied." + (ws-butler-mode nil) + (dolist (data-pair test-format-rob-elisp-data) + (let* ((testdata (car data-pair)) + (expected (cdr data-pair)) + (actual)) + (with-temp-buffer + (emacs-lisp-mode) + (insert testdata) + (goto-char (point-min)) + (set-mark (point)) + (goto-char (point-max)) + (message "buffer before:\n'%s'" (buffer-string)) + (cj/format-region-or-buffer) + (message "buffer after:\n'%s'" (buffer-string)) + (setq actual (buffer-string)) + (should (string= actual expected)))))) (provide 'test-format-region) ;;; test-format-region.el ends here. diff --git a/tests/test-title-case-region.el b/tests/test-title-case-region.el new file mode 100644 index 000000000..ffab0c241 --- /dev/null +++ b/tests/test-title-case-region.el @@ -0,0 +1,44 @@ +;;; test-title-case-region.el --- -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for the title-case region function in custom-functions.el + +;; Note on Title Case +;; Title case is a capitalization convention where major words are +;; capitalized,and most minor words are lowercase. Nouns,verbs (including +;; linking verbs), adjectives, adverbs,pronouns,and all words of four letters or +;; more are considered major words. Short (i.e., three letters or fewer) +;; conjunctions, short prepositions,and all articles are considered minor +;; words." + +;; positive case (single line, all lowercase, no skip words) +;; positive case (six lines, mixed case, skip words) +;; negative case (single line, all skip-words) +;; negative case (a long empty string) + + +;;; Code: + +(require 'ert) +(add-to-list 'load-path (concat user-emacs-directory "modules")) +(require 'custom-functions) + +(ert-deftest test-cj/fixup-whitespace-positive-first-line-only () + "Test a positive case with two lines. +Both lines have whitespace at the beginning and the end. This tests that when +this function is called on the first line, only that line is affected." + (let ((testdata " Hello, world! \n Foo bar ") + (expected "Hello, world!\n Foo bar ") + (actual)) + (with-temp-buffer + (insert testdata) + (goto-char (point-min)) + (cj/fixup-whitespace-line-or-region) + (setq actual (buffer-string)) + (should (string= actual expected))))) + + + + +(provide 'test-title-case-region) +;;; test-title-case-region.el ends here. |
