Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

swapLeft(), swapRight()

Dev Player
2011-09-13
2013-01-25
  • Dev Player
    Dev Player
    2011-09-13

    Here are two Python scripts. swapLeft() (Ctrl+Left) and swapRight() (Ctrl+Right) that swap words (and spaces).

    I wrote them because I didn't find any word swapping macros and such and I wanted to get my feet wet with Python scripts for Notepad++>

    These are my first Notepad++ scripts. I can not tell you how happy I am to see a Python plugin of this calibur for Notepad++. Thanks Dave. I added a lot of comments to the scripts to help others learn. I tried to reduce the Undo steps that other approaches might add. I tried my hand as making the scripts a little less fragile (ie. if you run these Python scripts outside Notepad++,  and bounds checking). Added a novice hack to produce some debug messages. And at the bottom of each script is a commented block if you don't like all that "fat" code. I'm sorry but I like tabs instead of 4 spaces in my Python code so you'll have to search and replace them for Pythonic like formatting. By the way, making these scripts made me realize that Notepad++ has a <> hot key but not > (greaterthan) or < (lessthen) hot keys. I'd like to put  in a request for that as I'd like to add a character swap. These scripts by the way are easy to adapt to do left/right word part swapping i.e. (blackmoon -> moonblack) just by adding tests if you are in-word or at word-boundries. I like the unexpected behavior if when you are in a whitespace area larger then one character that it swaps that whitespace area with the word. And I like being put back at the character position of the word I started the swap script from even after is is moved. A major enhancement tha tcan be done (if you feel up to it)is to test what file type you are in and move non-alpha characters with those words (or not depending on hotkey) for example ( <b>Hello</b> <i>World</i>  ==>> <i>World</i> <b>Hello</b>  or <b>Hello</b> <i>World</i>  ==>> <b>World</b> <i>Hello</i>)

    I'll post the scripts swapLeft() and swapRight() in following replies to this topic.

    Enjoy.

     
  • Dev Player
    Dev Player
    2011-09-13

    DevPlayer@Gmail.com 2011-09-12

    # swapLeft.py
    # Python Plugin for Notepad++
    # See bottom of code for succinct version
    '''Swap words, leaving middle whitespace(s) & non-word chars 
    in place, between words, as they were.
    Recommend assigning this script Plugin swapLeft() to: Ctrl + Left
    '''
    # a more robust version
    def swapLeft(*args, **kwargs):
        '''Swap current word with word on left.'''
        # Test to see if this Python module is being ran within 
        # Notepad++ and that the Npp.py plugin is imported
        # otherwise exit.
        if not globals().has_key('editor') :
            fail = False
            try:
                # import Npp will work within Notepad++
                # even if Npp.py is not installed in Python's packages
                # Also this code will not even run if the Notepad++
                # Python Plugin is not insalled so that test
                # is irrevelent.
                import Npp
            except ImportError:
                fail = True
            if fail is False:
                if not isinstance(globals()['editor'], (Npp.Editor,)):
                    fail = True
            if fail is True:
                print('This Python script is meant to be run within '\
                    ' Notepad++ with the Notepad++ Python Plugin installed.')
                # This Python module is not being run in correct place. 
                # Terminate.
                return None
        # The test <if __name__ == '__main__':> 
        # is placed within this function instead of 
        # this Python's global namespace to reduce 
        # clutter in notepad++'s global Python NS.
        # Oddly executing <if __name__ ..> put __name__ in globals().
        if kwargs.has_key('debug') and __name__ == '__main__':
            console.write('__main__.swapLeft()\n')
        # open a empty document and copy and paste the text after and before
        # the triple-quotes and into the empty document to test swapLeft()
        copy_to_an_editor_and_use_to_test = '''
    test
    test
        wordone wordtwo     wordthree   wordfour
        '''
        # because i'm a lazy typer.
        e = editor
        # save current position
        pos = e.getCurrentPos()
        # If we're at the beginning of the file, don't swap.
        if pos <= 0:
            # There's nothing to swap with on the left.
            if kwargs.has_key('debug'):
                console.write('Beginning of file. Nothing to swap with.\n')
            return None
        else:
            # There is probably something to the left that can be
            # swapped with.
            # save right word info
            wR = e.getWord()    # wR == original right word
            wRs = e.wordStartPosition(e.getCurrentPos(), True)
            wRe = e.wordEndPosition(e.getCurrentPos(), True)
            if kwargs.has_key('debug'):
                console.write('%r: %d - %d \n' % (wR, wRs, wRe))
            # goto left word (if there is one)
            e.wordLeftEnd()  
            # swapRight() does not use wordRightEnd() but wordRight()
            # save left word info
            wL = e.getWord()    # wL = original left word
            wLs = e.wordStartPosition(e.getCurrentPos(), True)
            wLe = e.wordEndPosition(e.getCurrentPos(), True)
            if kwargs.has_key('debug'):
                console.write('%r: %d - %d \n' % (wL, wLs, wLe))
            if wL == wR:
                # don't create an Undo's
                if kwargs.has_key('debug'):
                    console.write('Same word. No swap neccessary.\n')
                return None
            # copy left word, middle and right word from editor
            text = e.getTextRange(wLs, wRe)
            # erase left word from temp buffer # FIX:TEST order may matter on EOL
            txt_no_wL = text.replace(wL, '')
            # erase right word from temp buffer
            middle = txt_no_wL.replace(wR, '')
            # rebuild temp-buffer with left and right words swapped 
            # keeping middle as it was originally, between both words
            newText = wR + middle + wL
            # select all original text in editor 
            # from start of left word 
            # to end of right word
            e.setSel(wLs, wRe)
            # now replace old text with new text == one Undo step
            e.replaceSel(newText)
            # move back to left word character position
            # calculate original char position in left word
            wOffset = pos - len(middle) - len(wL)
            # now go back to char pos of new Left word
            e.gotoPos(wOffset)
            return None
    # debug=False equals debug=True;
    # Remove debug=whatever from parameters to turn off debug messages.
    #swapLeft(debug=True)
    swapLeft()
    # #########################################################################
    # ACTUAL REVELENT NON CHECKING CODE; 
    # copy the lines below uncommented; will work into swapLeft.py
    # pos = editor.getCurrentPos()
    # if pos == 0: return None # Not needed; used to reduce Undos
    # wR = editor.getWord()
    # wRs = editor.wordStartPosition(editor.getCurrentPos(), True)
    # wRe = editor.wordEndPosition(editor.getCurrentPos(), True)
    # editor.wordLeftEnd()  
    # wL = editor.getWord()
    # wLs = editor.wordStartPosition(editor.getCurrentPos(), True)
    # wLe = editor.wordEndPosition(editor.getCurrentPos(), True)
    # if wR == wL: return None  # not needed; Used to reduce Undos
    # text = editor.getTextRange(wLs, wRe)
    # txt_no_wL = text.replace(wL, '')
    # middle = txt_no_wL.replace(wR, '')
    # newText = wR + middle + wL
    # editor.setSel(wLs, wRe)
    # editor.replaceSel(newText)
    # wOffset = pos - len(middle) - len(wL)
    # editor.gotoPos(wOffset)
    # del pos, wR, wRs, wRe, wL, wLs, wLe, text, txt_no_wL, middle, newText
    # del wOffset
    # #########################################################################
    
     
  • Dev Player
    Dev Player
    2011-09-13

    DevPlayer@Gmail.com 2011-09-12

    # swapRight.py
    # Python Plugin for Notepad++
    # See bottom of code for succinct version
    '''Swap words, leaving middle whitespace(s) & non-word chars 
    in place, between words, as they were.
    Recommend assigning this script Plugin swapLeft() to: Ctrl + Right
    '''
    # a more robust version
    def swapRight(*args, **kwargs):
        '''Swap current word with word on right.'''
        # Test to see if this Python module is being ran within 
        # Notepad++ and that the Npp.py plugin is imported
        # otherwise exit.
        if not globals().has_key('editor') :
            fail = False
            try:
                # import Npp will work within Notepad++
                # even if Npp.py is not installed in Python's packages
                # Also this code will not even run if the Notepad++
                # Python Plugin is not insalled so that test
                # is irrevelent.
                import Npp
            except ImportError:
                fail = True
            if fail is False:
                if not isinstance(globals()['editor'], (Npp.Editor,)):
                    fail = True
            if fail is True:
                print('This Python script is meant to be run within '\
                    ' Notepad++ with the Notepad++ Python Plugin installed.')
                # This Python module is not being run in correct place. 
                # Terminate.
                return None
        # The test <if __name__ == '__main__':> 
        # is placed within this function instead of 
        # this Python's global namespace to reduce 
        # clutter in notepad++'s global Python NS.
        # Oddly executing <if __name__ ..> put __name__ in globals().
        if kwargs.has_key('debug') and __name__ == '__main__':
            console.write('__main__.swapLeft()\n')
        # open a empty document and copy and paste the text after and before
        # the triple-quotes and into the empty document to test swapLeft()
        copy_to_an_editor_and_use_to_test = '''
    test
    test
        wordone wordtwo     wordthree   wordfour
        '''
        # because i'm a lazy typer.
        e = editor
        # save current position
        pos = e.getCurrentPos()
        # If we're at the end of the file, don't swap
        if pos >= e.getLength():
            # There's nothing to swap with on the right. 
            if kwargs.has_key('debug'):
                console.write('End of file. Nothing to swap with.\n')
            return None
        else:
            # There is probably something to the right that can be
            # swapped with.
            # save left word info
            wL = e.getWord()    # wL == original left word
            wLs = e.wordStartPosition(e.getCurrentPos(), True)
            wLe = e.wordEndPosition(e.getCurrentPos(), True)
            if kwargs.has_key('debug'):
                console.write('%r: %d - %d \n' % (wL, wLs, wLe))
            # goto right word (if there is one)
            e.wordRight()
            #e.wordRightEnd()
            # save right word info
            wR = e.getWord()    # wR == original rigth word
            wRs = e.wordStartPosition(e.getCurrentPos(), True)
            wRe = e.wordEndPosition(e.getCurrentPos(), True)
            if kwargs.has_key('debug'):
                console.write('%r: %d - %d \n' % (wR, wRs, wRe))
            if wL == wR:
                # don't create an Undo's
                if kwargs.has_key('debug'):
                    console.write('Same word. No swap neccessary.\n')
                return None
            # copy left word, middle and right word from editor
            text = e.getTextRange(wLs, wRe)
            # erase left word from temp buffer # FIX:TEST order may matter on EOL
            txt_no_wL = text.replace(wL, '')
            # erase right word from temp buffer
            middle = txt_no_wL.replace(wR, '')
            # rebuild temp-buffer with left and right words swapped 
            # keeping middle as it was originally, between both words
            newText = wR + middle + wL
            # select all original text in editor 
            # from start of left word 
            # to end of right word
            e.setSel(wLs, wRe)
            # now replace old text with new text == one Undo step
            e.replaceSel(newText)
            # move back to left word character position
            # calculate original char position in word 1
            wOffset = len(wR) + len(middle) + pos
            # now go back to char pos of new Right word
            e.gotoPos(wOffset)
            return None
    # debug=False equals debug=True;
    # Remove debug=whatever from parameters to turn off debug messages.
    #swapRight(debug=True)
    swapRight()
    # #########################################################################
    # ACTUAL REVELENT NON CHECKING CODE; 
    # copy the lines below uncommented; will work into swapLeft.py
    # pos = e.getCurrentPos()
    # if pos >= e.getLength(): return None # Not needed; used to reduce Undos
    # wL = e.getWord()
    # wLs = e.wordStartPosition(e.getCurrentPos(), True)
    # wLe = e.wordEndPosition(e.getCurrentPos(), True)
    # e.wordRight()
    # wR = e.getWord()
    # wRs = e.wordStartPosition(e.getCurrentPos(), True)
    # wRe = e.wordEndPosition(e.getCurrentPos(), True)
    # if wL == wR: return None # Not needed; used to reduce Undos
    # text = e.getTextRange(wLs, wRe)
    # txt_no_wL = text.replace(wL, '')
    # middle = txt_no_wL.replace(wR, '')
    # newText = wR + middle + wL
    # e.setSel(wLs, wRe)
    # e.replaceSel(newText)
    # wOffset = len(wR) + len(middle) + pos
    # e.gotoPos(wOffset)
    # del pos, wR, wRs, wRe, wL, wLs, wLe, text, txt_no_wL, middle, newText
    # del wOffset
    # #########################################################################