From 6936f5b60b61dcf41cbda75813d7f259733eedf2 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 3 May 2026 06:56:10 -0500 Subject: fix(line-paragraph): join-line-or-region strands space on next line The region branch's `(while (< (point) end) (join-line 1))` ran one iteration too many. After the final in-region join, point sat just before the end marker, so the loop fired once more. That extra `join-line 1` consumed the next line's preceding newline and replaced it with a space. Then `(goto-char end)` + `(newline)` reinserted a newline at the original end position, before the inserted space, so the space ended up stranded at BOL of the next line. I replaced the position-based loop with `count-lines` + `dotimes` to do exactly the right number of joins. I also swapped the trailing `(newline)` for `(forward-line 1)`. The bullet-list use case now lands directly on the next existing line with no blank gap. The trailing-newline change ripples to `cj/join-paragraph` (which delegates here), so paragraphs now also stop adding a trailing newline when the input lacks one. `require-final-newline` handles file-end discipline on save anyway. I added 3 new tests that fail against the old loop and pass against the fix. I also updated 11 existing tests whose assertions baked in the old trailing-newline behavior. While in there I wrapped the `cj/custom-keymap` defvar stub in `eval-and-compile` in both test files. The bare defvar wasn't evaluated at byte-compile time, so the `require` of `custom-line-paragraph` would hit a void symbol when the validate-el hook ran. --- modules/custom-line-paragraph.el | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'modules/custom-line-paragraph.el') diff --git a/modules/custom-line-paragraph.el b/modules/custom-line-paragraph.el index 32f9aaa1..4b0baa90 100644 --- a/modules/custom-line-paragraph.el +++ b/modules/custom-line-paragraph.el @@ -24,13 +24,19 @@ "Join lines in the active region or join the current line with the previous one." (interactive) (if (use-region-p) - (let ((beg (region-beginning)) - (end (copy-marker (region-end)))) + ;; Compute the join count up front from the region's line span. + ;; A position-based loop overshoots — after the final in-region join, + ;; point still sits before the end marker, so one extra `join-line 1` + ;; reaches past the region and pulls the next line in, leaving a stray + ;; space at its head when the trailing newline is reinserted. + (let* ((beg (region-beginning)) + (end (copy-marker (region-end))) + (n (count-lines beg end))) (goto-char beg) - (while (< (point) end) + (dotimes (_ (max 0 (1- n))) (join-line 1)) (goto-char end) - (newline) + (forward-line 1) (deactivate-mark)) ;; No region - only join if there's a previous line (when (> (line-number-at-pos) 1) -- cgit v1.2.3