Something like transpose

Something like transpose

Post by rbielaw » Sun, 05 Sep 2004 04:15:26


I rarely manage to say what I mean the first time I type something.
So I'm often re-organizing what I just wrote. To make this easier
I'm looking for a function that does something like transpose but
allows for a connecting phrase. For example if I type

I want that over there but not this over here.

and later I decide I said it wrong, I could select

that over there but not this over here

then type `C-x t' or whatever and then select the connecting phrase

but not

And I would get

I want this over here but not that over there.

Does anything resembling this already exist?
If not, can anyone suggest how one could go about allowing
the 2nd selection to be made from within the C-x t invoked function?
 
 
 

Something like transpose

Post by John Thing » Sun, 05 Sep 2004 04:55:55


I think what most peaple use are the mark, cut and yank commands.

C-\space at the beginning
move the cursor to the ned
C-w to delete the text
move to the secone area you want do mark
C-\space
move to the end
C-w
now nove to the place you want the second text inserted
C-y
now move to the place you want the first text insertted
C-y M-y gets the first text out of the yank buffer

(last 16 kills are recorded in the yank buffer M-y allows you to step
through
them to find the one you want)

This seems to do the trick in most cases but if you do this a lot you
might want to create a macro.

C-x-( commands X-x-)
to run
C-x-e
or bind it to your favorite funtion key
As always C-h-i for the manual will give you what you need.
select keyboard macroes

--
Using M2, Opera's revolutionary e-mail client: http://www.yqcomputer.com/

 
 
 

Something like transpose

Post by Michael Sl » Sun, 05 Sep 2004 05:27:02


XXXX@XXXXX.COM (rgb) writes:



Try this:
(defun transpose-around-phrase (beg end phrase)
"Transpose portions of the region around an anchor PHRASE.
PHRASE is literal text that must appear in the region, surrounded by one or more
non-word characters. The non-word characters will not be transposed, but will be
treated as part of the anchor phrase."
(interactive "r\nsTranspose around phrase: ")
(save-excursion
(save-restriction
(narrow-to-region beg end)
(beginning-of-buffer)
(if (re-search-forward (concat "\\(.*?\\)\\(\\W+" phrase "\\W+\\)\\(.*\\)") nil t)
(replace-match (concat (match-string 3) (match-string 2) (match-string 1)))
(message "Can't find non-word-surrounded phrase \"%s\" in the region" phrase)))))

It doesn't do anything smart about capitalization, and it will
transpose ALL of the region (including trailing periods, if you
include them --- which is almost undoubtedly NOT what you want), so
for now, don't select the punctuation at the end of the sentence.

You can glue this in before the (narrow-to-region ...) call, if you
want to include the closing punctuation in the region (which is what
end-of-sentence will do) but not in the swap.

(goto-char (1- end))
(while (looking-at "[.!?]")
(setq end (1- end))
(goto-char (1- end)))

It's a hack, but it should get you started.
--
Mike Slass
 
 
 

Something like transpose

Post by rbielaw » Thu, 09 Sep 2004 00:01:11

> >I'm looking for a function that does something like transpose but


Yes, good idea, thanks.
 
 
 

Something like transpose

Post by Michael Sl » Thu, 09 Sep 2004 06:03:16


XXXX@XXXXX.COM (rgb) writes:


If you improve upon it with use, please repost; I'd use it too.

--
Mike Slass
 
 
 

Something like transpose

Post by rbielaw » Sat, 25 Sep 2004 10:36:44


Mine is perhaps even a bit more rough than your version was.
With mine you still need to be careful to select surrounding
whitespace when selecting the anchor text. It's just because
I've been too lazy to fix it. It's more complex in my case
because I sometimes use this to on formulas and other non-text.

Although I really liked the simplicity with which you handled
the white space around the anchor point, the regexp had the
dissadvantage of sometimes finding the wrong anchor if it
appeared more than once. Also, regexp's don't always handle
multi-line transpositions well.

(global-set-key [?\C-x ?t] 'anchored-transpose)

(defvar anchored-transpose-anchor ()
"begin/end when `anchored-transpose' is in progress else nil")

(defun anchored-transpose (beg end &optional beg2 end2)
"Transpose portions of the region around an anchor PHRASE.
`this phrase and that word' can be transposed into
`that word and this phrase'

by selecting the entire phrase followed by \\[anchored-transpose].
Then select the anchor phrase ` and ' including any surrounding
whitespace that shouldn't move and type \\[anchored-transpose] again.

You can select the anchor phrase first followed by the phrase to be
transposed if more convenient. Typing \\[anchored-transpose] with
nothing selected clears any prior selection."
(interactive `(,(region-beginning) ,(region-end)
,@anchored-transpose-anchor))
(setq anchored-transpose-anchor nil deactivate-mark t)
(if mark-active
(if end2 ; then both regions are marked. swap them.
(if (and (< beg beg2)
(> end end2))
(anchored-transpose-swap beg beg2 end2 end)
(if (and (> beg beg2)
(< end end2))
(anchored-transpose-swap beg2 beg end end2)
(error "Regions have invalid overlap")))
;; 1st of 2 regions. Save it and wait for the other.
(setq anchored-transpose-anchor (list beg end))
(message "Select other part (anchor or region)"))
(error "anchored-transpose requires a marked region")))

(defun anchored-transpose-swap (reg1beg reg1end reg2beg reg2end)
;; I still need to add fuzzyness to the boundaries. For example if
;; char-before reg2end is .?! or if reg2beg is looking-at whitespace
;; etc. For me it needs to be mode specific though, so it's work:(
(let* ((reg1 (buffer-substring reg1beg reg1end))
(reg2 (delete-and-extract-region reg2beg reg2end)))
(goto-char reg2beg)
(insert reg1)
(save-excursion ;; I want to leave point at the end of phrase 2.
(goto-char reg1beg)
(delete-region reg1beg reg1end)
(insert reg2))))
 
 
 

Something like transpose

Post by rbielaw » Sat, 25 Sep 2004 10:36:44


Mine is perhaps even a bit more rough than your version was.
With mine you still need to be careful to select surrounding
whitespace when selecting the anchor text. It's just because
I've been too lazy to fix it. It's more complex in my case
because I sometimes use this to on formulas and other non-text.

Although I really liked the simplicity with which you handled
the white space around the anchor point, the regexp had the
dissadvantage of sometimes finding the wrong anchor if it
appeared more than once. Also, regexp's don't always handle
multi-line transpositions well.

(global-set-key [?\C-x ?t] 'anchored-transpose)

(defvar anchored-transpose-anchor ()
"begin/end when `anchored-transpose' is in progress else nil")

(defun anchored-transpose (beg end &optional beg2 end2)
"Transpose portions of the region around an anchor PHRASE.
`this phrase and that word' can be transposed into
`that word and this phrase'

by selecting the entire phrase followed by \\[anchored-transpose].
Then select the anchor phrase ` and ' including any surrounding
whitespace that shouldn't move and type \\[anchored-transpose] again.

You can select the anchor phrase first followed by the phrase to be
transposed if more convenient. Typing \\[anchored-transpose] with
nothing selected clears any prior selection."
(interactive `(,(region-beginning) ,(region-end)
,@anchored-transpose-anchor))
(setq anchored-transpose-anchor nil deactivate-mark t)
(if mark-active
(if end2 ; then both regions are marked. swap them.
(if (and (< beg beg2)
(> end end2))
(anchored-transpose-swap beg beg2 end2 end)
(if (and (> beg beg2)
(< end end2))
(anchored-transpose-swap beg2 beg end end2)
(error "Regions have invalid overlap")))
;; 1st of 2 regions. Save it and wait for the other.
(setq anchored-transpose-anchor (list beg end))
(message "Select other part (anchor or region)"))
(error "anchored-transpose requires a marked region")))

(defun anchored-transpose-swap (reg1beg reg1end reg2beg reg2end)
;; I still need to add fuzzyness to the boundaries. For example if
;; char-before reg2end is .?! or if reg2beg is looking-at whitespace
;; etc. For me it needs to be mode specific though, so it's work:(
(let* ((reg1 (buffer-substring reg1beg reg1end))
(reg2 (delete-and-extract-region reg2beg reg2end)))
(goto-char reg2beg)
(insert reg1)
(save-excursion ;; I want to leave point at the end of phrase 2.
(goto-char reg1beg)
(delete-region reg1beg reg1end)
(insert reg2))))
 
 
 

Something like transpose

Post by Michael Sl » Sun, 26 Sep 2004 05:04:37


XXXX@XXXXX.COM (rgb) writes:



Wow! You really ran with that. I'm going to try yours for a bit and
see how it works. I'll post any changes/fixes/suggestions.

Nice job.

--
Mike Slass
 
 
 

Something like transpose

Post by rbielaw » Sun, 26 Sep 2004 07:26:09

gt; > >> >I'm looking for a function that does something like transpose but

I'm quite sorry I started thinking about it. Allowing fuzzy
selection opens several cans of worms. Not the least of which is
how to turn it off if you don't want it. Same for dealing with
capitalization in the phrases and where point should be left when
the transpose is complete....

This version:

1) Makes whitespace around anchor part of the anchor phrase.
2) Drops a trailing .!? if found at the end of the selection.
3) Provides a way to interactively turn off fuzzy selection.
4) Provides a way to make the fuzzy algorithm mode specific
or just replace it globally with your own.

Lots more description than code. I can't seem to be brief.

;; (c) RGB 2004
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

(defun anchored-transpose (beg end flg &optional beg2 end2 flg2)
"Transpose portions of the region around an anchor phrase.

`this phrase but not that word' can be transposed into
`that word but not this phrase'

First select the entire phrase and type \\[anchored-transpose]. Then
select the anchor phrase `but not' and type \\[anchored-transpose] again.
By default the anchor phrase will automatically include any surrounding
whitespace even if you don't specifically select it. Also, it won't
include certain trailing punctuation. See `anchored-transpose-do-fuzzy'.

You can select the anchor phrase first followed by the phrase to be
transposed if more convenient. Typing \\[anchored-transpose] with
nothing selected clears any prior selection."
(interactive `(,(region-beginning) ,(region-end)
,current-prefix-arg
,@anchored-transpose-anchor))
(setq anchored-transpose-anchor nil deactivate-mark t)
(if mark-active
(if end2 ; then both regions are marked. swap them.
(if (and (< beg beg2)
(> end end2))
(apply 'anchored-transpose-swap
(anchored-transpose-do-fuzzy
beg beg2 end2 end flg flg2))
(if (and (> beg beg2)
(< end end2))
(apply 'anchored-transpose-swap
(anchored-transpose-do-fuzzy
beg2 beg end end2 flg2 flg))
(error "Regions have invalid overlap")))
;; 1st of 2 regions. Save it and wait for the other.
(setq anchored-transpose-anchor (list beg end flg))
(message "Select other part (anchor or region)"))
(error "Command requires a marked region")))

;; EVERYTHING PAST THIS POINT IS ONLY SUPPORTING CODE.
(defvar anchored-transpose-anchor ()
"begin/end when `anchored-transpose' is in progress else nil")

(defun anchored-transpose-do-fuzzy (r1beg r1end r2beg r2end flg flg2)
"Returns the arguments supplied after adjusting their value if necessary.

r1beg and r1end define a region to be transposed with the other region
defined by r2beg and r2end. r1end and r2beg de