New Caps Lock Functionality

I am Windows user, and I use Autohotkey (www.autohotkey.com) to make scripts to optimize the work I do on my computer. However, my girlfriend has a Mac, and there’s one thing she sees me do that she’d especially like to be able to do on her Mac. It isn’t extremely complicated, and I was wondering if it would be possible with AppleScript. Here’s what I need to do: I want to set Caps Lock so that if the user has any text highlighted, then double-tapping that key will replace the highlighted text with the same, but CAPITALIZED, characters if at least one of those characters is a lower-case letter. Otherwise, that text should be replaced with the same characters, but all in lower-case. Here’s some sample input and output…

HIGHLIGHTED TEXT NEW TEXT
“abcde” “ABCDE”
“ABCDe” “ABCDE”
“ABCDE” “abcde”

I would like to thank anyone who’s willing to help (and possibly even write the script for me?) VERY MUCH in advance. I would also like to add that although I’m a Windows user, I am definitely not looking for a fight on this forum. Let’s please just all respect each other, and help a fellow human being make his girlfriend happy!

Hi,

first, nobody will be bashed in this forum because of his faith :wink:

Unfortunately AppleScript can’t do everything you described, so its quite complicated to realize it.
The user interaction capabilities are restricted, so you need an application like QuicKeys or iKey to detect a keystroke.
The function to change the case is not natively built in AppleScript but there is an Scripting Addition which makes this possible.

when you say any text highlighted, are you talking about highlighted in a particular app

Interesting. Actually doing the swap isn’t difficult - the script below will do what I think was wanted. What I haven’t achieved is to get the commented-out parts to work when I run the script with a key command from FastScripts (or, for that matter from QuicKeys). The failure is in copying and pasting.

set UC to "ABCDEFGHIJKLMNOPQRSTUVWXYZ" as Unicode text
set LC to "abcdefghijklmnopqrstuvwxyz" as Unicode text
(*tell application "System Events"
	set P to name of first process whose frontmost is true
	activate
	tell process P to keystroke "c" using {command down}
end tell*)
set myWords to {"Some", "TEXT", "samples", "hERe"}
set New to {}
repeat with W in myWords
	--set c to characters of (the clipboard)
	set c to characters of W
	set Nchrs to count c
	set Lcc to {}
	set Loff to {}
	considering case
		repeat with k from 1 to Nchrs
			if item k of c is in LC then
				set end of Lcc to k
				set end of Loff to offset of (item k of c) in LC
			end if
		end repeat
		if Lcc = {} then
			repeat with k from 1 to Nchrs
				set ouc to offset of (item k of c) in UC
				set item k of c to character ouc of LC
			end repeat
		else if Nchrs > (count Lcc) then -- at least one is LC, but not all
			repeat with k from 1 to count Lcc
				set item (item k of Lcc) of c to character (item k of Loff) of UC
			end repeat
		else if Nchrs = (count Lcc) and Lcc ≠ {} then -- all characters are LC
			repeat with k from 1 to Nchrs
				set olc to offset of (item k of c) in LC
				set item k of c to character olc of UC
			end repeat
		end if
	end considering
	set end of New to c as string --> {"SOME", "text", "SAMPLES", "HERE"}
end repeat
(*
set the clipboard to c as string
activate application P
tell application "System Events" to tell process P to keystroke "v" using {command down}
*)

Adam,

I fired your script (from Quickeys) and apart from focus getting lost from the front app while copying/pasting via system events, the script worked very well.
So for textedit, I omitted the first “activate” command and then it works.
Different applications seem to behave differently (getting the text selection is even worse, but you might try to compare with the clipboard and use the better result)

It will be a pain to make this script really universal, though.

Thanks Eelco;

So I discovered. Getting the script to grab the selection from BBEdit, TextWrangler, TextEdit, and Eudora seemed to be impossible without customization and getting it to paste the answer back was worse.

There is a Dashboard widgit called “Case Converter” that I use all the time to change things to all upper, all lower, initial caps, or sentence case.

If none of these scripting solutions works, you could try the widgit. You can download it form the widgit section on Apple’s site.

Model: G5 Tower (not Intel) - Script Editor ver 2.1.1
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

The reason you’re having so much trouble copying/pasting is because you’re not getting the name of the front application correctly with the “set P to name of first process whose frontmost is true” statement. I changed it and added a needed delay after the copy command. In order to get the script to work on more than one word at a time, I had to make adjustment in the changing case from “ALL UPPER” words to “all lower” words section. There was a problem with the script acting on a between 2 words in that section. Here’s a script that works in several apps I tested it in.

So to use it, just save it as an application from script editor, save it to your users scripts folder at ~/Library/Scripts, then when you need it it’s ready to go. And as far as setting a hot-key to call the script look here… http://applescriptsourcebook.com/viewtopic.php?pid=46901


set UC to "ABCDEFGHIJKLMNOPQRSTUVWXYZ" as Unicode text
set LC to "abcdefghijklmnopqrstuvwxyz" as Unicode text

set p to displayed name of (info for (path to frontmost application))
tell application p to activate -- get the name of the front application
tell application "System Events" to tell process p to keystroke "c" using command down -- copy the highlighted word to the clipboard
delay 0.2

set New to {}

set c to characters of (the clipboard)
set Nchrs to count c
set Lcc to {}
set Loff to {}

considering case
	repeat with k from 1 to Nchrs
		if item k of c is in LC then
			set end of Lcc to k
			set end of Loff to offset of (item k of c) in LC
		end if
	end repeat
	if Lcc = {} then
		repeat with k from 1 to Nchrs
			if item k of c is not " " then
				set ouc to offset of (item k of c) in UC
				set item k of c to character ouc of LC
			end if
		end repeat
	else if Nchrs > (count Lcc) then -- at least one is LC, but not all
		repeat with k from 1 to count Lcc
			set item (item k of Lcc) of c to character (item k of Loff) of UC
		end repeat
	else if Nchrs = (count Lcc) and Lcc ≠ {} then -- all characters are LC
		repeat with k from 1 to Nchrs
			set olc to offset of (item k of c) in LC
			set item k of c to character olc of UC
		end repeat
	end if
end considering

set the clipboard to c as string
tell application "System Events" to tell process p to keystroke "v" using command down