As an author, I frequently have to swap two words, phrases or sentences. I do that by dragging and dropping or by using the clipboard history, or by retyping, all of which are cumbersome and prone to mistakes.
Example: after selecting 'short' and 'simple' in the sentence 'This is a short and simple example' and swapping them, the sentence would become 'This is a simple and short example'
Example: place two cursors in the above sentence, one in the word 'simple' and one in 'short', and they'll be automatically selected and reversed.
For swapping a word and a phrase, it would be handy if I could select the word by Ctrl-clicking and the phrase by dragging to have it automatically selected (that is, a combination of 1 and 2).
More generally, I would like to be able to invert any number of selections of any length anywhere in a document.
Simple example: the text 'a b c d e f g' with the a, the c, the e and the g selected becomes 'g b e d c f a'.
Obviously swapping two selections is a special case of reversing any number of selections.
Here is a JavaScript macro for EmEditor to swap multiple selections or words at the cursor positions.
Redraw = false; // optimize for speed
CombineHistory = true; // combine Undo
nMax = document.selection.Count; // retrieve the number of selections
ax = Array( nMax );
ax2 = Array( nMax );
ay = Array( nMax );
ay2 = Array( nMax );
as = Array( nMax );
for( i = 0; i < nMax; ++i ) { // retrieve position of each selection
ax[i] = document.selection.GetTopPointX( eePosLogical, i + 1 );
ax2[i] = document.selection.GetBottomPointX( eePosLogical, i + 1 );
ay[i] = document.selection.GetTopPointY( eePosLogical, i + 1 );
ay2[i] = document.selection.GetBottomPointY( eePosLogical, i + 1 );
}
for( i = 0; i < nMax; ++i ) { // retrieve word text and positions
if( ax[i] == ax2[i] && ay[i] == ay2[i] ) {
document.selection.SetActivePoint( eePosLogical, ax[i], ay[i] ); // set cursor position
document.selection.SelectWord(); // select a word
ax[i] = document.selection.GetTopPointX( eePosLogical ); // retrieve selection position
ax2[i] = document.selection.GetBottomPointX( eePosLogical );
as[i] = document.selection.Text; // retrieve selected text
}
else {
document.selection.SetActivePoint( eePosLogical, ax[i], ay[i] );
document.selection.SetActivePoint( eePosLogical, ax2[i], ay2[i], true );
as[i] = document.selection.Text; // retrieve selected text
}
}
for( i = nMax - 1; i >= 0; --i ) { // set a selection from bottom to top
document.selection.SetActivePoint( eePosLogical, ax[i], ay[i] );
document.selection.SetActivePoint( eePosLogical, ax2[i], ay2[i], true );
document.selection.Text = as[nMax - i - 1]; // set new text
}
To run this, save this code as, for instance, Macro.jsee
, and then select this file from Select... in the Macros menu. Finally, select Run Macro.jsee in the Macros menu while multiple selections are made.