Ironically, the selection expansion is the problem in both cases. Just happens to be two very different problems.
The Select Lines command handles emoji just fine, but it accounts for almost half the run time of the entire dmbrown-fuzzywan script. Combining the two approaches â call it dmbrown-fuzzywan-peavine, or dfp for short â shaves off 10â20ms, but pure peavine is still twice as fast. And dfp doesnât persist the selection. SighâŠ
FWIW, I thought one of the four NSString properties that normalize strings might allow my script to work with emojiâs but that wasnât the case. As far as I can tell, the four normalize properties simply ignore emojis, although my knowledge on this topic is quite limited.
Normalize accented letters, which apparently are already 16-bit code units. This works as I would expect.
Hmm. Since count (characters of (theString as text)) gives a different result â ââ has a length of 2 and count of 1 â that gives me a starting point.
The difference between the count and length of everything prior to cr1 could be used as an adjustment factor. Something like this:
on getParagraphRange(theCode, cr1, cr2)
set theCode to current application's NSString's stringWithString:theCode
-- Adjustment factor for characters wider than one UTF-16 code unit, like emoji.
set leftString to characters 1 thru (cr1 - 1) of (theCode as text) as string
set leftString to current application's NSString's stringWithString:leftString
set codeUnitFactor to (leftString's |length|()) - (count (characters of (leftString as text)))
-- Adjust something (?) here.
set paragraphRange to theCode's paragraphRangeForRange:{(cr1 - 1), cr2}
return {((paragraphRange's location) + 1), paragraphRange's |length|}
end getParagraphRange
That gives me the right numbers â ââ has a an adjustment factor of 1, and ââ has a factor of 3 due to the skin tone modifier â but using it to adjust cr1 doesnât have the effect I expected. It looks like the original selection itself is off by codeUnitFactor, so that needs to be adjusted somehow. Iâm not sure if itâs possible.
I rewrote my script in post 9 to incorporate the selection ASObjC range property, as suggested by Shane. This cleans up the code a bit but does not alter the basic operation of the script.
use framework "Foundation"
use scripting additions
on main()
set commentCharacters to "--"
tell application "Script Debugger" to tell document 1
set allCode to source text
set {cr1, cr2} to selection ASObjC range
set {pr1, pr2} to getParagraphRange(allCode, cr1, cr2) of me
set selection ASObjC range to {pr1, pr2}
set selectedCode to selection
set {editedCode, editCount, editAction} to getEditedCode(selectedCode, commentCharacters) of me
set contents of selection to editedCode
set pr2 to (pr2 + ((count commentCharacters) * editCount * editAction))
set selection ASObjC range to {pr1, pr2}
end tell
end main
on getParagraphRange(theString, cr1, cr2)
set theString to current application's NSString's stringWithString:theString
set paragraphRange to theString's paragraphRangeForRange:{cr1, cr2}
return {paragraphRange's location, paragraphRange's |length|}
end getParagraphRange
on getEditedCode(theString, theCharacters)
set removeString to current application's NSMutableString's stringWithString:theString
set addString to current application's NSMutableString's stringWithString:theString
set removeCount to removeString's replaceOccurrencesOfString:("(?m)^(\\h*)" & theCharacters) withString:"$1" options:1024 range:{0, removeString's |length|()}
set addCount to addString's replaceOccurrencesOfString:"(?m)^(\\h*)" withString:(theCharacters & "$1") options:1024 range:{0, addString's |length|()}
if removeCount is equal to addCount then return {removeString as text, removeCount, "-1"}
return {addString as text, addCount, "1"}
end getEditedCode
main()
Applying the adjustment factor to cr1 or pr1 either makes things much, much worse, or in some cases (subtracting it from cr1) has no effect at all. And since cr1 is setting pr1 (I think?), I donât get why the effects are wildly different. Iâm clearly not understanding how that part works.
fuzzywan. Can you test my revised script in post 24 with a script that contains emojis. I think it may have resolved that issue. I didnât fully understand the operation of the selection ASObjC range property and may have confused matters.
Itâs the zero-based range in 16-bit units â thatâs what NSString works in.
Basically, if youâre going to manipulate text using normal AppleScript, use selection; if youâre going to be converting it to an NSString and manipulating it using ASObjC, use selection ASObjC range.
Iâll be damned. Iâd made some changes based on Shaneâs selection ASObjC range suggestion, but I must have missed part of it because it was working exactly the same as the original.
how does one run this script (post #24) on a different script â i.e. not on itself ? Do I have to use a tool like FastScript to do it?
EDIT> just discovered the User Scripts Folder, and it hot-loads new scripts, nice. now I just need to assign a keyboard control⊠I wonder if Apples Shortcuts Settings are up for that?!