mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 09:14:18 +00:00
Fix aligning buffer regions containing multiple alignment sections
* lisp/align.el (align-region): Use markers to ensure the regions stay accurate after overlapping aligning modifications. (Bug#80316) * test/lisp/align-tests.el (align-c-multi-section): New test.
This commit is contained in:
parent
3ea1010a6b
commit
fd6d8faa62
2 changed files with 77 additions and 8 deletions
|
|
@ -1407,11 +1407,18 @@ aligner would have dealt with are."
|
|||
(align-region
|
||||
beg end 'entire
|
||||
exclude-rules nil
|
||||
;; Use markers for exclusion area bounds so
|
||||
;; they remain accurate after subsequent
|
||||
;; alignment sections modify the buffer.
|
||||
(lambda (b e mode)
|
||||
(or (and mode (listp mode))
|
||||
(let ((bm (copy-marker b))
|
||||
(em (copy-marker e t)))
|
||||
(push bm markers)
|
||||
(push em markers)
|
||||
(setq exclude-areas
|
||||
(cons (cons b e)
|
||||
exclude-areas)))))
|
||||
(cons (cons bm em)
|
||||
exclude-areas))))))
|
||||
(setq exclude-areas
|
||||
(nreverse
|
||||
(sort exclude-areas #'car-less-than-car))))
|
||||
|
|
@ -1458,12 +1465,15 @@ aligner would have dealt with are."
|
|||
(setq same nil)
|
||||
(align--set-marker eol (line-end-position)))
|
||||
|
||||
;; remember the beginning position of this rule
|
||||
;; match, and save the match-data, since either
|
||||
;; the `valid' form, or the code that searches for
|
||||
;; section separation, might alter it
|
||||
(setq rule-beg (match-beginning first)
|
||||
save-match-data (match-data))
|
||||
;; Remember the beginning position of this rule
|
||||
;; match as a marker so it remains accurate after
|
||||
;; `align-regions' modifies the buffer for a
|
||||
;; previous alignment section. Also save the
|
||||
;; match-data, since either the `valid' form, or
|
||||
;; the code that searches for section separation,
|
||||
;; might alter it.
|
||||
(align--set-marker rule-beg (match-beginning first) t)
|
||||
(setq save-match-data (match-data))
|
||||
|
||||
(or rule-beg
|
||||
(error "No match for subexpression %s" first))
|
||||
|
|
@ -1480,6 +1490,18 @@ aligner would have dealt with are."
|
|||
(when (and last-point
|
||||
(align-new-section-p last-point rule-beg
|
||||
thissep))
|
||||
;; Convert saved match-data positions to
|
||||
;; markers before `align-regions' modifies
|
||||
;; the buffer, so the restored match-data
|
||||
;; reflects the updated buffer state.
|
||||
(setq save-match-data
|
||||
(mapcar (lambda (pos)
|
||||
(if (integerp pos)
|
||||
(let ((m (copy-marker pos)))
|
||||
(push m markers)
|
||||
m)
|
||||
pos))
|
||||
save-match-data))
|
||||
(align-regions regions align-props rule func)
|
||||
(setq regions nil)
|
||||
(setq align-props nil))
|
||||
|
|
|
|||
|
|
@ -36,6 +36,53 @@
|
|||
(ert-test-erts-file (ert-resource-file "c-mode.erts")
|
||||
(test-align-transform-fun #'c-mode)))
|
||||
|
||||
(ert-deftest align-c-multi-section ()
|
||||
"Test alignment of multiple sections in C code.
|
||||
Regression test for bug where positions become stale after earlier
|
||||
sections are aligned, causing incorrect alignment in later sections."
|
||||
(let ((input "int main(void)
|
||||
{
|
||||
long signed int foo = 5;
|
||||
int bar = 7;
|
||||
{
|
||||
int a1 = 4;
|
||||
int b1 = 2;
|
||||
long signed int junk1 = 2;
|
||||
}
|
||||
{
|
||||
int a2 = 4; /* comment */
|
||||
int b2 = 2;
|
||||
long signed int junk2 = 2; /* another comment */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
(expected "int main(void)
|
||||
{
|
||||
long signed int foo = 5;
|
||||
int bar = 7;
|
||||
{
|
||||
int a1 = 4;
|
||||
int b1 = 2;
|
||||
long signed int junk1 = 2;
|
||||
}
|
||||
{
|
||||
int a2 = 4; /* comment */
|
||||
int b2 = 2;
|
||||
long signed int junk2 = 2; /* another comment */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
"))
|
||||
(with-temp-buffer
|
||||
(c-mode)
|
||||
(setq indent-tabs-mode nil)
|
||||
(insert input)
|
||||
(align (point-min) (point-max))
|
||||
(should (equal (buffer-string) expected)))))
|
||||
|
||||
(ert-deftest align-css ()
|
||||
(let ((indent-tabs-mode nil))
|
||||
(ert-test-erts-file (ert-resource-file "css-mode.erts")
|
||||
|
|
|
|||
Loading…
Reference in a new issue