Subject: bug#21766: 25.0.50; delete-trailing-whitespace sometimes deletes non-whitespace

From: Andreas Röhler <[email-masked]>
Date: Tue, 27 Oct 2015 08:07:38 +0100

On 27.10.2015 01:15, Juanma Barranquero wrote:
> On Tue, Oct 27, 2015 at 12:07 AM, Markus Triska <[email-masked] 
> <mailto:[email-masked]>> wrote:
> >
> >
> > Steps to reproduce:
> >
> > 1) wget http://www.metalevel.at/ei/fault1.html
> >
> > 2) emacs -Q fault1.html
> >
> > 3) M-x delete-trailing-whitespace RET
> >
> > This removes several non-white-space characters, including the whole
> > line containing "and use it like" (line 83 in the original file),
>
> Apparently, the call to skip-syntax-backward is altering the match 
> data. If you try this
>
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -609,7 +609,7 @@ delete-trailing-whitespace
>              (start (or start (point-min))))
>          (goto-char start)
>          (while (re-search-forward "\\s-$" end-marker t)
> -          (skip-syntax-backward "-" (line-beginning-position))
> +          (save-match-data (skip-syntax-backward "-" 
> (line-beginning-position)))
>            ;; Don't delete formfeeds, even if they are considered 
> whitespace.
>            (if (looking-at-p ".*\f")
>                (goto-char (match-end 0)))
>
>
> or, alternatively,
>
> @@ -609,11 +609,12 @@ delete-trailing-whitespace
>              (start (or start (point-min))))
>          (goto-char start)
>          (while (re-search-forward "\\s-$" end-marker t)
> -          (skip-syntax-backward "-" (line-beginning-position))
> -          ;; Don't delete formfeeds, even if they are considered 
> whitespace.
> -          (if (looking-at-p ".*\f")
> -              (goto-char (match-end 0)))
> -          (delete-region (point) (match-end 0)))
> +          (let ((end (match-end 0)))
> +            (skip-syntax-backward "-" (line-beginning-position))
> +            ;; Don't delete formfeeds, even if they are considered 
> whitespace.
> +            (if (looking-at-p ".*\f")
> +                (goto-char end))
> +            (delete-region (point) end)))
>          ;; Delete trailing empty lines.
>          (goto-char end-marker)
>          (when (and (not end)
>
> it works.

First fix looks cleaner.

> Now, the question is, should skip-syntax-backward preserve the match 
> data, or must delete-trailing-whitespace be coded defensively? The 
> usual policy has been that code that needs the match data preserved 
> should make sure itself that it is so.

Such a basic routine should preserve matches by its own virtue.

A couple of regression tests should pay here.

Thanks