Davey - 2015-02-24

Hi
I often have to swap 2 words that are not adjacent to eachother
So I wrote a little python script and figured I'd share it
(There are 2 other threads that have similar but different functionalities. see one by Dev Player and another by kabiner)

This script works only with 2 selections
If the selection has a length, then the script uses those chars, otherwise, it will use the word under the cursor
After the script swaps the words, it sets a full selection on each of the 2 words swapped (just to show the actual swap)
There is an undo actions started at the beginning of the script, and ended at the end. This way, one control+z will undo the action (instead of 2)

def getWord_Sel(selNum):    # tuple of:  word, word_start, word_end
    sPos = editor.getSelectionNStart(selNum)
    ePos = editor.getSelectionNEnd(selNum)
    if sPos != ePos:
        sWrd = editor.getTextRange(sPos, ePos)
    else:
        sPos = editor.wordStartPosition(sPos, True)
        ePos = editor.wordEndPosition(sPos, True)
        sWrd = editor.getTextRange(sPos, ePos)

    return (sWrd, sPos, ePos)

def replaceWords(var1, var2):
    editor.setTarget(var2[1], var2[2])
    editor.replaceTarget(var1[0])
    editor.setTarget(var1[1], var1[2])
    editor.replaceTarget(var2[0])
    return len(var2[0]) - len(var1[0])

def setSels(var1, var2, diff):
    editor.setSelection(var1[1], var1[1]+len(var2[0]))
    editor.addSelection(var2[1]+diff, var2[1]+diff+len(var1[0]))

selsCt = editor.getSelections()
if selsCt == 2:
    editor.beginUndoAction()

    tSel1 = getWord_Sel(0)
    tSel2 = getWord_Sel(1)
    if tSel1[1] < tSel2[1]:
        sel1, sel2 = tSel1, tSel2
    else:
        sel1, sel2 = tSel2, tSel1

    diff = replaceWords(sel1, sel2)
    setSels(sel1, sel2, diff)

    editor.endUndoAction()


Hope others can find this helpful as well

Davey