I don't think there is any keybinding context
key that will help to differentiate between text that is uppercase and text that is lowercase.
But you can use an extension that I wrote to do this: Find and Transform.
Create this keybinding in your keybindings.json
:
{
"key": "alt+d", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "((([a-z])|([A-Z]))(.*))", // is the first letter upper of lowercase?
"replace": "${3:+${1:/upcase}}${4:+${1:/downcase}}",
"isRegex": true,
"matchCase": true, // this must be set to true to distinguish cases
"restrictFind": "selections", // works on your selection(s), one or many
}
}

As you can see, it tests the first letter. If it is lowercase a-z
, then the selection is uppercased. And vice-versa, if the first letter is [A-Z]
, then the selection is lowercased.
If you can have digits, underscores or other non-alphabetic characters as the first character, this simple first-letter matching won't work and you would have to keep testing characters which would make for a messy regex, but could probably be done. [Let me know if you need that, I think I know how it can be done, although it is a different approach.]
The replacement:
"replace": ${3:+${1:/upcase}}${4:+${1:/downcase}}
is pretty interesting. The $n
's refer to capture groups from the find regex. ${3:+${1:/upcase}}
means if there is a capture group 3 (the first letter is [a-z]
, then upcase all of capture group 1.
And similarly if the first letter is [A-Z]
, so there is a capture group 4, then it and the rest of the selection, capture group 1, will be lowercased.
In a normal vscode snippet or keybinding you can not embed a capture group inside a conditional like ${3:+${1:/upcase}}
. ${3:+text to add here if group 3}
normally takes only text and cannot resolve variables or capture groups, much less transform their case like ${1:/upcase}
inside the conditional - but the extension can.