# 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 Mappertext=editor.getSelText()iftext:#DothisonlyifsometexthasbeenselectedcheckingFuncs=[lambdas:s.isupper(),lambdas:s.islower(),lambdas:s.istitle(),lambdas:True]alteringFuncs=[lambdas:s.lower(),lambdas:s.title(),lambdas:s.upper(),lambdas:s.upper()]numOfFuncs=len(checkingFuncs)foriinrange(0,numOfFuncs):#IteratethroughthelistofcheckingfunctionsifcheckingFuncs[i](text):#Checktheexistingcaseofthetexttext=alteringFuncs[i](text)#Basedontheresultofcheckingfunction,changethecaseinthisorder:upper->lower,lower->title,title->upper,anythingelse->upperbreakstart=editor.getSelectionStart()#Recordthestartandendpositionoftheselectionend=editor.getSelectionEnd()editor.replaceSel(text)#Replacetheoriginallyselectedtextwithaltered-casetext,thiswillendtheselectionaswelleditor.setSel(start,end)#Selectthenewlyalteredtext
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
# Edited to include changes suggested by Rufus in the commentstext=editor.getSelText()iftext:# tuples of check and alter functionsfunctable=[(lambdas:s.isupper(),lambdas:s.lower()),(lambdas:s.islower(),lambdas:s.title()),(lambdas:s.istitle(),lambdas:s.upper()),(lambdas:True,lambdas:s.upper())]forcheck,alterinfunctable:# Iterate through the list of checking and altering functionsifcheck(text):text=alter(text)breakstart=editor.getSelectionStart()end=editor.getSelectionEnd()editor.replaceSel(text)editor.setSel(start,end)
Last edit: Abbas 2014-11-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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(lambdas:s.isupper(),lambdas:s.lower()),(lambdas:s.islower(),lambdas:s.title()),(lambdas:s.istitle(),lambdas:s.upper()),(lambdas:True,lambdas:s.upper())]forcheck,alterinfunctable:ifcheck(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.)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Excellent suggestion, indexing into the arrays always troubled me subconsciously, and while I too am a lazy typist, the improvement in code was too good to just use the zip function. I have updated my post.
The only change I made was assign text to the alter functions return value.
Please continue to share suggestions. Will look forward to your script contributions as well.
Regards,
Abbas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you very much for sharing this code segment. It has been very nice tool to get introduced to a few concpets relating to Python and this Add-on for Notepad++.
I do hope you do not mind me making some contribution - hoping others will learn as much as I have. See below the small expansion.
Dan
'''
Title: MS Word-style case change (Shift+F3 feature):
change the case of selected text from upper to lower to title
Creator: Abbas
Publish: https://sourceforge.net/p/npppythonscript/discussion/1199074/thread/b0cc797e/
NOTES:
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
UPDATES: _ver_ _description_
2013-08-11 Abbas 1.0.0 Original release
2014-11-16 Abbas 1.1.0 Edited to include changes suggested by Rufus in the comments
2017-06-05 Dan Padric 1.1.1 Formatting, commentary, add "Sentence case" & error message
'''
text = editor.getSelText() # Absorb selected text into tag
if text: # PROCESSING TEXT
# tuples of check and alter functions
functable = [
(lambda s: s.isupper(), lambda s: s.lower()), # ............ UPPER CASE -> lower case
(lambda s: s.islower(), lambda s: s[0].upper()
+ s[1:].lower()), # .... lower case -> Sentence case
(lambda s: s[0].isupper()
and s[1:].islower(), lambda s: s.title()), # ............ Sentence case -> Title Case
(lambda s: s.istitle(), lambda s: s.upper()), # ............ Title Case -> UPPER CASE
(lambda s: True, lambda s: s.upper()) # ............. {none} -> UPPER CASE
]
for check, alter in functable: # Iterate through the list of checking and altering functions
if check(text): # ........... TEST
text = alter(text) # .... MODIFY
break # ................. task complete
start = editor.getSelectionStart()
end = editor.getSelectionEnd() # ... positioning of current selection
editor.replaceSel(text) # ....... replace text with modified version
editor.setSel(start, end) # ..... reselect text
else: # NO TEXT SELECTED
action = notepad.messageBox('No selection made', # .. error message
'Text case toggle',
MESSAGEBOXFLAGS.OK)
Last edit: Dan Padric 2017-06-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Nice work Dan! I just have one suggestion to make it act more like Word...
Instead of displaying a messageBox if no selection is made, you could automatically select the current word and apply the modification to that.
# Select the "word" at current cursor position
pos = editor.getCurrentPos()
begin = editor.wordStartPosition(pos,True)
end = editor.wordEndPosition(pos,True)
editor.setSel(start, end)
# Transform word case
text = editor.getSelText()
text = alter(text)
editor.replaceSel(text)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yep. Take the string 'two words' for example. When the cursor is "on" whitespace it could be to the left of the space ('two| ') or to the right of it (' |words'). Eiher way, wordStartPosition() and wordEndPosition() return the begining and end of the "word" the cursor is touching. If you place the cursor between two spaces (e.g. 'two | spaces') then wordStartPosition() == wordEndPosition() == getCurrentPos().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Dan, I encountered a little problem when trying to implement my suggestion, i.e. for a single word 's[0].isupper() and s[1:].islower() == s.title()'. So, when cycling through case changes for a single word, it would get stuck in the the sentance/title case and never proceeds to the upper case. I was able to work around this by changing the order of your functable.
Here is the updated code.
#Title: MS Word-style case change (Shift+F3 feature): # change the case of selected text from upper to lower to title #Creator: Abbas #Publish: https://sourceforge.net/p/npppythonscript/discussion/1199074/thread/b0cc797e/#NOTES: # 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#UPDATES: _ver_ _description_# 2013-08-11 Abbas 1.0.0 Original release # 2014-11-16 Abbas 1.1.0 Edited to include changes suggested by Rufus in the comments# 2017-06-05 Dan Padric 1.1.1 Formatting, commentary, add "Sentence case" & error message# 2017-08-24 David Hansen 1.2.0 Support for changing case of a word without needing to select it first# tuples of check and alter functionsfunctable=[(lambdas:s.isupper(),lambdas:s.lower()),# ............ UPPER CASE -> lower case(lambdas:s.istitle(),lambdas:s.upper()),# ............ Title Case -> UPPER CASE(lambdas:s.islower(),lambdas:s[0].upper()+s[1:].lower()),# .... lower case -> Sentence case(lambdas:s[0].isupper()ands[1:].islower(),lambdas:s.title()),# ............ Sentence case -> Title Case(lambdas:True,lambdas:s.upper())# ............. {none} -> UPPER CASE]text=editor.getSelText()# Absorb selected text into tagifnottext:# then no selection is made# select the current wordpos=editor.getCurrentPos()start=editor.wordStartPosition(pos,True)end=editor.wordEndPosition(pos,True)editor.setSel(start,end)text=editor.getSelText()forcheck,alterinfunctable:# Iterate through the list of checking and altering functionsifcheck(text):# ........... TESTtext=alter(text)# .... MODIFYbreak# ................. task completestart=editor.getSelectionStart()end=editor.getSelectionEnd()# ... positioning of current selectioneditor.replaceSel(text)# ....... replace text with Modified Versioneditor.setSel(start,end)# ..... Reselect Text
Last edit: David Hansen 2017-08-24
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
:::python
Last edit: Abbas 2014-11-26
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:
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:
(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.)
Excellent suggestion, indexing into the arrays always troubled me subconsciously, and while I too am a lazy typist, the improvement in code was too good to just use the zip function. I have updated my post.
The only change I made was assign text to the alter functions return value.
Please continue to share suggestions. Will look forward to your script contributions as well.
Regards,
Abbas
Hello.
Thank you very much for sharing this code segment. It has been very nice tool to get introduced to a few concpets relating to Python and this Add-on for Notepad++.
I do hope you do not mind me making some contribution - hoping others will learn as much as I have. See below the small expansion.
Last edit: Dan Padric 2017-06-05
Nice work Dan! I just have one suggestion to make it act more like Word...
Instead of displaying a messageBox if no selection is made, you could automatically select the current word and apply the modification to that.
Hi David. A very valid point you are making. Did you test the result with the cursor on whitespace - in the space between two words?
Yep. Take the string 'two words' for example. When the cursor is "on" whitespace it could be to the left of the space ('two| ') or to the right of it (' |words'). Eiher way, wordStartPosition() and wordEndPosition() return the begining and end of the "word" the cursor is touching. If you place the cursor between two spaces (e.g. 'two | spaces') then wordStartPosition() == wordEndPosition() == getCurrentPos().
Hi Dan, I encountered a little problem when trying to implement my suggestion, i.e. for a single word 's[0].isupper() and s[1:].islower() == s.title()'. So, when cycling through case changes for a single word, it would get stuck in the the sentance/title case and never proceeds to the upper case. I was able to work around this by changing the order of your functable.
Here is the updated code.
Last edit: David Hansen 2017-08-24
David, thanks for sharing your addition.
This demonstrates why I like community driven code.
Talk to you again some time.