Subject: Re: bug#67925: 29.1; delete-rectangle fails on multi-column characters

From: Eli Zaretskii <[email-masked]>
Date: Thu, 21 Dec 2023 10:42:35 +0200

> From: [email-masked]
> Cc: [email-masked]
> Date: Thu, 21 Dec 2023 16:30:39 +0900
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > Thanks.  Does the patch below give good results?
> >
> > diff --git a/lisp/rect.el b/lisp/rect.el
> > index 8dc188b..9049e32 100644
> > --- a/lisp/rect.el
> > +++ b/lisp/rect.el
> > @@ -212,7 +212,10 @@ rectangle-dimensions
> >        (cons width height))))
> >  
> >  (defun delete-rectangle-line (startcol endcol fill)
> > -  (when (= (move-to-column startcol (if fill t 'coerce)) startcol)
> > +  ;; We use >= here, not =, for characters that use more than one
> > +  ;; column on display, when STARTCOL is in the middle of such a
> > +  ;; character.
> > +  (when (>= (move-to-column startcol (if fill t 'coerce)) startcol)
> >      (delete-region (point)
> >  		   (progn (move-to-column endcol 'coerce)
> >  			  (point)))))
> 
> This patch gives similar result of kill-rectangle.
> In the example above, I want all '4' characters moved to same column.

How can that be done, when the first character takes 2 or more
columns?  Deleting the first character is IMO wrong, since the other
lines leave the first character intact.  Adding SPC to other lines is
also wrong, since delete-rectangle is not supposed to _add_ columns.

So I think the effect you see after the patch I proposed is the only
reasonable outcome.  If that is not good enough for keeping the layout
of some table (as you hint in your original report, without showing
any details about the mode used in that case), then Lisp programs
which allow you to keep such tables aligned should be modified to do
something that cannot be done in general by delete-rectangle.

IOW, the general issue in delete-rectangle cannot do anything smarter
than the above, I think, and any solution specific to some particular
implementation or use of rectangles will have to be fixed by code
specific to that particular implementation (if that is some mode that
is part of Emacs).

> And TAB characters crossing the end column are not edited correctly
> with delete-rectangle if indent-tabs-mode is on.
> 
> 012345678
> 	8(TAB at head)
> 012345678
> 
> The text above is edited to the text below.
> 45678
> 	8(TAB at head)
> 45678
> 
> If indent-tabs-mode is off, the result is the text below.
> 45678
>     8(four SPCs)
> 45678

This is a separate issue with the original code.  It also happens with
kill-rectangle, btw.  We could fix it by temporarily binding
indent-tabs-mode to nil inside these commands -- would that be
acceptable?  The result will be that the killed rectangle includes
spaces, not the leading TAB.