diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-11 14:29:03 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-11 14:29:03 -0500 |
| commit | 016f322de184b09d79cb1d7db522a0aaa6c00a9f (patch) | |
| tree | f3ca3d8607244a71953fd9616e53ed7445853094 /modules | |
| parent | 1ba475cb0cf7076a284b13d808029309d13ea08c (diff) | |
| download | dotemacs-016f322de184b09d79cb1d7db522a0aaa6c00a9f.tar.gz dotemacs-016f322de184b09d79cb1d7db522a0aaa6c00a9f.zip | |
fix(custom-ordering): preserve the trailing newline in reverse and number
cj/reverse-lines and cj/number-lines split the region on newlines without accounting for a trailing one, so it became a spurious empty element. Reversing "a\nb\n" floated that empty to the top ("\nb\na"), and numbering added a phantom final numbered line. Both now strip a trailing newline before splitting and reattach it after, matching cj/--arrayify, while preserving internal blank lines. Corrected the two tests that asserted the broken output.
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/custom-ordering.el | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/modules/custom-ordering.el b/modules/custom-ordering.el index 4dc5bff8..71477948 100644 --- a/modules/custom-ordering.el +++ b/modules/custom-ordering.el @@ -145,8 +145,15 @@ START and END identify the active region." START and END define the region to operate on. Returns the transformed string without modifying the buffer." (cj/--ordering-validate-region start end) - (let ((lines (split-string (buffer-substring start end) "\n"))) - (mapconcat #'identity (nreverse lines) "\n"))) + ;; Strip a trailing newline before splitting so it doesn't become a spurious + ;; empty line (which reversing would float to the top); reattach it after. + ;; Internal blank lines are preserved. + (let* ((raw (buffer-substring start end)) + (trailing-newline (string-suffix-p "\n" raw)) + (body (if trailing-newline (substring raw 0 -1) raw)) + (lines (split-string body "\n"))) + (concat (mapconcat #'identity (nreverse lines) "\n") + (if trailing-newline "\n" "")))) (defun cj/reverse-lines (start end) "Reverse the order of lines in region between START and END. @@ -164,20 +171,28 @@ ZERO-PAD when non-nil pads numbers with zeros for alignment. Example with 100 lines: \"001\", \"002\", ..., \"100\". Returns the transformed string without modifying the buffer." (cj/--ordering-validate-region start end) - (let* ((lines (split-string (buffer-substring start end) "\n")) + ;; Strip a trailing newline before splitting so it doesn't become a spurious + ;; extra numbered empty line; reattach it after. Internal blank lines are + ;; preserved and numbered. + (let* ((raw (buffer-substring start end)) + (trailing-newline (string-suffix-p "\n" raw)) + (body (if trailing-newline (substring raw 0 -1) raw)) + (lines (split-string body "\n")) (line-count (length lines)) (width (if zero-pad (length (number-to-string line-count)) 1)) (format-spec (if zero-pad (format "%%0%dd" width) "%d"))) - (mapconcat - (lambda (pair) - (let* ((num (car pair)) - (line (cdr pair)) - (num-str (format format-spec num))) - (concat (replace-regexp-in-string "N" num-str format-string) line))) - (cl-loop for line in lines - for i from 1 - collect (cons i line)) - "\n"))) + (concat + (mapconcat + (lambda (pair) + (let* ((num (car pair)) + (line (cdr pair)) + (num-str (format format-spec num))) + (concat (replace-regexp-in-string "N" num-str format-string) line))) + (cl-loop for line in lines + for i from 1 + collect (cons i line)) + "\n") + (if trailing-newline "\n" "")))) (defun cj/number-lines (start end format-string zero-pad) "Number lines in region between START and END with custom format. |
