summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-05-05 09:23:58 -0500
committerCraig Jennings <c@cjennings.net>2024-05-05 09:34:19 -0500
commit4566ec69d269ecba8d9386a131b932ee5244aa8e (patch)
treefa00edae4ba8c93eee7861fa795052511d4e0f29
parent5f19638abc20eb24511a4129df2be09e1554591c (diff)
downloaddotemacs-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-contents3
-rw-r--r--.localrepo/libmpdel-20230816.839.tarbin0 -> 61440 bytes
-rw-r--r--.localrepo/mpdel-20230903.915.tarbin0 -> 51200 bytes
-rw-r--r--.localrepo/navigel-20230903.835.tarbin0 -> 30720 bytes
-rw-r--r--assets/abbrev_defs20
-rw-r--r--assets/elfeed-feeds.org1
-rw-r--r--early-init.el2
-rw-r--r--init.el1
-rw-r--r--modules/config-utilities.el35
-rw-r--r--modules/custom-functions.el118
-rw-r--r--modules/dirvish-config.el7
-rw-r--r--modules/org-config.el1
-rw-r--r--modules/org-roam-config.el2
-rw-r--r--modules/prog-lisp.el14
-rw-r--r--modules/record-desktop.el61
-rw-r--r--modules/selection-framework.el4
-rw-r--r--modules/system-defaults.el69
-rw-r--r--modules/test-code.el63
-rw-r--r--modules/text-config.el4
-rw-r--r--modules/user-constants.el7
-rw-r--r--tests/test-clear-blank-lines.el47
-rw-r--r--tests/test-fixup-whitespace.el159
-rw-r--r--tests/test-format-region.el129
-rw-r--r--tests/test-title-case-region.el44
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
new file mode 100644
index 000000000..7c6f93cb8
--- /dev/null
+++ b/.localrepo/libmpdel-20230816.839.tar
Binary files differ
diff --git a/.localrepo/mpdel-20230903.915.tar b/.localrepo/mpdel-20230903.915.tar
new file mode 100644
index 000000000..061c57586
--- /dev/null
+++ b/.localrepo/mpdel-20230903.915.tar
Binary files differ
diff --git a/.localrepo/navigel-20230903.835.tar b/.localrepo/navigel-20230903.835.tar
new file mode 100644
index 000000000..2c9864857
--- /dev/null
+++ b/.localrepo/navigel-20230903.835.tar
Binary files differ
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 ----------------------------
diff --git a/init.el b/init.el
index 4f5134ac0..751840e03 100644
--- a/init.el
+++ b/init.el
@@ -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.