Move interactive `transpose-regions' to Lisp

Define `transpose-regions' in Lisp, because its complex interactive
spec was ungainly in C, and change the C version to non-interactive
`transpose-regions-internal'.  The Lisp function is just a wrapper
around the C function, which still does all the work.

* lisp/simple.el (transpose-regions): New wrapper function, with
  interactive spec taken from old C `transpose-regions'.

* src/editfns.c (Ftranspose_regions): Rename to...
  (Ftranspose_regions_internal): ...here, and remove interactive spec.

Discussion on Emacs Devel:

  From: Karl Fogel
  To: Emacs Development
  Cc: Richard Copley, Charles A. Roelli
  Subject: Re: [Emacs-diffs] master b88e7c8: \
           Make transpose-regions interactive (Bug#30343)
  Date: Fri, 16 Mar 2018 10:23:31 -0500
  Message-ID: <87po44jb7w.fsf@red-bean.com>

  https://lists.gnu.org/archive/html/emacs-devel/2018-03/msg00555.html
This commit is contained in:
Karl Fogel 2018-03-18 16:43:18 -05:00
parent 9667ba25b4
commit 3a3aa0e056
2 changed files with 31 additions and 19 deletions

View file

@ -7014,6 +7014,34 @@ With argument 0, interchanges line point is in with line mark is in."
(forward-line arg)))) (forward-line arg))))
arg)) arg))
(defun transpose-regions (startr1 endr1 startr2 endr2 &optional leave-markers)
"Transpose region STARTR1 to ENDR1 with STARTR2 to ENDR2.
The regions should not be overlapping, because the size of the buffer is
never changed in a transposition.
Optional fifth arg LEAVE-MARKERS, if non-nil, means don't update
any markers that happen to be located in the regions.
Transposing beyond buffer boundaries is an error.
Interactively, STARTR1 and ENDR1 are point and mark; STARTR2 and ENDR2
are the last two marks pushed to the mark ring; LEAVE-MARKERS is nil.
If a prefix argument N is given, STARTR2 and ENDR2 are the two
successive marks N entries back in the mark ring. A negative prefix
argument instead counts forward from the oldest mark in the mark
ring."
(interactive
(if (< (length mark-ring) 2)
(error "Other region must be marked before transposing two regions")
(let* ((num (if current-prefix-arg
(prefix-numeric-value current-prefix-arg)
0))
(ring-length (length mark-ring))
(eltnum (mod num ring-length))
(eltnum2 (mod (1+ num) ring-length)))
(list (point) (mark) (elt mark-ring eltnum) (elt mark-ring eltnum2)))))
(transpose-regions-internal startr1 endr1 startr2 endr2 leave-markers))
;; FIXME seems to leave point BEFORE the current object when ARG = 0, ;; FIXME seems to leave point BEFORE the current object when ARG = 0,
;; which seems inconsistent with the ARG /= 0 case. ;; which seems inconsistent with the ARG /= 0 case.
;; FIXME document SPECIAL. ;; FIXME document SPECIAL.

View file

@ -5112,16 +5112,7 @@ transpose_markers (ptrdiff_t start1, ptrdiff_t end1,
} }
} }
DEFUN ("transpose-regions", Ftranspose_regions, Stranspose_regions, 4, 5, DEFUN ("transpose-regions-internal", Ftranspose_regions_internal, Stranspose_regions_internal, 4, 5, 0,
"(if (< (length mark-ring) 2)\
(error \"Other region must be marked before transposing two regions\")\
(let* ((num (if current-prefix-arg\
(prefix-numeric-value current-prefix-arg)\
0))\
(ring-length (length mark-ring))\
(eltnum (mod num ring-length))\
(eltnum2 (mod (1+ num) ring-length)))\
(list (point) (mark) (elt mark-ring eltnum) (elt mark-ring eltnum2))))",
doc: /* Transpose region STARTR1 to ENDR1 with STARTR2 to ENDR2. doc: /* Transpose region STARTR1 to ENDR1 with STARTR2 to ENDR2.
The regions should not be overlapping, because the size of the buffer is The regions should not be overlapping, because the size of the buffer is
never changed in a transposition. never changed in a transposition.
@ -5129,14 +5120,7 @@ never changed in a transposition.
Optional fifth arg LEAVE-MARKERS, if non-nil, means don't update Optional fifth arg LEAVE-MARKERS, if non-nil, means don't update
any markers that happen to be located in the regions. any markers that happen to be located in the regions.
Transposing beyond buffer boundaries is an error. Transposing beyond buffer boundaries is an error. */)
Interactively, STARTR1 and ENDR1 are point and mark; STARTR2 and ENDR2
are the last two marks pushed to the mark ring; LEAVE-MARKERS is nil.
If a prefix argument N is given, STARTR2 and ENDR2 are the two
successive marks N entries back in the mark ring. A negative prefix
argument instead counts forward from the oldest mark in the mark
ring. */)
(Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers) (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers)
{ {
register ptrdiff_t start1, end1, start2, end2; register ptrdiff_t start1, end1, start2, end2;
@ -5581,5 +5565,5 @@ functions if all the text being accessed has this property. */);
defsubr (&Swiden); defsubr (&Swiden);
defsubr (&Snarrow_to_region); defsubr (&Snarrow_to_region);
defsubr (&Ssave_restriction); defsubr (&Ssave_restriction);
defsubr (&Stranspose_regions); defsubr (&Stranspose_regions_internal);
} }