MS Word-style case change (Shift+F3 feature): change the case of selected text from upper to lower to title

Abbas
2013-08-11
2014-09-10
  • Abbas
    Abbas
    2013-08-11

    :::python

    # MS Word has the option of changing the case of selected text by pressing Shift+F3
    # The case changes in the order: UPPER CASE, lower case, Title Case
    # It was something I was missing in Notepad++ so I wrote the following script to add the change case feature
    # Remember to associate this script with Shift+F3 key combination in the Shortcut Mapper
    
    text = editor.getSelText()
    
    if text: # Do this only if some text has been selected
        checkingFuncs = [lambda s: s.isupper(), lambda s: s.islower(),  lambda s: s.istitle(),  lambda s: True]
        alteringFuncs = [lambda s: s.lower(),   lambda s: s.title(),        lambda s: s.upper(),        lambda s: s.upper()]
        numOfFuncs = len(checkingFuncs)
    
        for i in range(0, numOfFuncs): # Iterate through the list of checking functions
            if checkingFuncs[i](text): # Check the existing case of the text
                text = alteringFuncs[i](text) # Based on the result of checking function, change the case in this order: upper->lower, lower->title, title->upper, anything else->upper
                break
    
        start = editor.getSelectionStart() # Record the start and end position of the selection
        end =   editor.getSelectionEnd()
    
        editor.replaceSel(text) # Replace the originally selected text with altered-case text, this will end the selection as well
    
        editor.setSel(start, end) # Select the newly altered text
    
     
  • Rufus V. Smith
    Rufus V. Smith
    2014-09-10

    Nicely done. The only issue I have is the need for indexing into arrays. I think it is prettier Python doing the checks and alters this way:

    functable = [  # tuples of check_function, alter_function
    (lambda s: s.isupper(), lambda s: s.lower()),
    (lambda s: s.islower(), lambda s: s.title()),
    (lambda s: s.istitle(), lambda s: s.upper()),
    (lambda s: True,        lambda s: s.upper())
    ]
    for check,alter in functable:
        if check(text): 
            alter(text)
            break
    

    You've inspired me to create a "invert case" function, because I'm forever typing labels with my caps-lock on!

    P.S. if you already have the first macro in and are a lazy typer like I am, you can just put the following line after your existing function tables:

    functable = zip(checkingFuncs, alteringFuncs)
    

    (I also like having checks and alters in a single list, so I don't have two lists to keep in sync if I decide to change one.)