AppleScript EnumList (Like Comma List)

Being inspired by the Comma List extension. One thing I do in my programming is creating a lot of Enums, sometimes with BitMask Options.
I’ll come up with a text list of what options I want for names, and then I always
have to do repeated entry of the same stuff over and over:

Going from:

        Checked_None
        Checked_Whitespace
        Checked_EpisodeID
        Checked_CatalogNo
        Checked_Composer
etc..

To:

        Checked_None = 0,
        Checked_Whitespace = 1 << 0,
        Checked_EpisodeID = 1 << 1,
        Checked_CatalogNo = 1 << 2,
        Checked_Composer = 1 << 3,
etc..

And Sometimes To Help Me with MultiMask I’ll Add Integer Values as Comments:

        Checked_None = 0,
	Checked_Whitespace = 1 << 0,					// 1
	Checked_EpisodeID = 1 << 1,					// 2
	Checked_CatalogNo = 1 << 2,					// 4
	Checked_Composer = 1 << 3,					// 8
etc.

And sometimes not using BitMasks but starting a different value than zero IE.5:

	Checked_None = 5,
	Checked_Whitespace = 6,
	Checked_EpisodeID = 7,
	Checked_CatalogNo = 8,
	Checked_Composer = 9,
etc.

See my AppleScript Code in next reply. Where I use options selected by Key
Modifier Masks:

DEFAULT - use bit mask mode
SHIFT - to add bit integer value comments
OPTION (ALT) - to turn off bit mask mode
COMMAND - to turn off bit mask mode and use different start offset
^^^^ in this mode the user is presented with a dialog to enter their start offset
(defaults to 1)

I’ll soon be packaging this to a PopClip Extension after testing some more:

1 Like

AppleScript Testing Code for Above…
I’ll soon be packaging this to a PopClip Extension after testing some more:
PopClip templates are there

	set sourceText to "{popclip text}"
	set modFlags to "{popclip modifier flags}"

but for testing I override and provide my own values.
two sourceText examples are included:

  1. a line separate list
  2. a comma separated list
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use framework "AppKit"

-- classes, constants, and enums used
property NSMutableString : a reference to current application's NSMutableString
property NSString : a reference to current application's NSString
property NSArray : a reference to current application's NSArray
property NSMutableArray : a reference to current application's NSMutableArray
property NSCharacterSet : a reference to current application's NSCharacterSet
property NSMutableCharacterSet : a reference to current application's NSMutableCharacterSet

property NSRegularExpressionSearch : a reference to 1024
property NSCommandKeyMask : a reference to 1048576 -- 0x100000
property NSAlternateKeyMask : a reference to 524288 -- 0x80000
property NSControlKeyMask : a reference to 262144 -- 0x40000
property NSShiftKeyMask : a reference to 131072 -- 0x20000

property hasCommand : false
property hasOption : false
property hasControl : false
property hasShift : false

property sourceText : ""
property modFlags : 0



property addBitValueComment : false
property useBitShift : true
property useOffset : false

property startOffset : 1
property longestLength : 0
property lengthPad : 10 -- adjust this for Comment TAB Padding
property tabText : "	"

property sourceLines : {}
property countLines : 0

property finalArray : {}
property finalString : ""



(*
	set sourceText to "{popclip text}"
	set modFlags to "{popclip modifier flags}"
*)

set sourceText to "Checked_None
Checked_Whitespace
Checked_EpisodeID
Checked_CatalogNo
Checked_Composer
Checked_Label
Checked_Rating
Checked_Show
Checked_Comments
Checked_Genre
Checked_MultiArtists
Checked_Quality
Checked_Dupes"

-- below for TESTING with comma seperated
--set sourceText to "Checked_None, Checked_Whitespace, Checked_EpisodeID, Checked_CatalogNo, Checked_Composer, Checked_Label, Checked_Rating, Checked_Show, Checked_Comments, Checked_Genre, Checked_MultiArtists, Checked_Quality, Checked_Dupes"

-- below for TESTING with nonBitShift mode
--set modFlags to NSAlternateKeyMask

-- below for TESTING with useOffset mode
--set modFlags to NSCommandKeyMask

-- below for TESTING with addBitValueComment mode
set modFlags to NSShiftKeyMask

my parseOptionsForModFlags:modFlags

set sourceString to (NSString's stringWithString:sourceText)
set sourceLines to (my splitString:sourceString)
set countLines to sourceLines's |count|()

if (countLines > 0) then
	my parseLines()
end if

if (finalArray's |count|() > 0) then
	set finalString to (finalArray's componentsJoinedByString:"
")
end if

if (finalString's |length|() > 0) then
	tell application "System Events"
		set finalText to finalString as text
		delay 0.02
		set the clipboard to finalText
		delay 0.5
		keystroke "v" using {command down}
		keystroke return
		delay 0.02
	end tell
end if

on parseLines()
	set aKeyPath to "@max.length"
	set longestLength to (sourceLines's valueForKeyPath:aKeyPath)'s integerValue()
	set longestLength to longestLength + lengthPad
	set finalArray to (NSMutableArray's new())
	repeat with i from 0 to (countLines - 1)
		set aNewLine to (sourceLines's objectAtIndex:i)
		set aSuffix to (my createSuffixForIndex:i)
		set aFinalLine to (aNewLine's stringByAppendingString:aSuffix)
		(finalArray's addObject:aFinalLine)
	end repeat
end parseLines

on createSuffixForIndex:aIndex
	set aSuffix to (NSMutableString's new())
	set isFirstIndex to (aIndex is 0)
	set notLastIndex to (aIndex is not (countLines - 1))
	set aShift to 0
	
	if (useBitShift or useOffset) then
		set aValue to (NSMutableString's stringWithString:" = ")
		
		if (useBitShift) then
			if (isFirstIndex) then
				(aValue's appendString:"0")
			else
				set aShift to (aIndex - 1)
				(aValue's appendFormat_("1 << %@", aShift))
			end if
		else
			set aShift to (aIndex + startOffset)
			(aValue's appendFormat_("%@", aShift))
		end if
		
		(aSuffix's appendString:aValue)
	end if
	
	if (notLastIndex) then
		(aSuffix's appendString:",")
	end if
	
	if (addBitValueComment and not isFirstIndex) then
		set aComment to (NSMutableString's new())
		
		set aLineLength to (sourceLines's objectAtIndex:aIndex)'s |length|()
		set aSuffixLength to aSuffix's |length|()
		if (aSuffixLength > lengthPad) then set aSuffixLength to lengthPad
		set aFillLength to (longestLength + aSuffixLength - aLineLength)
		set aTabCount to (round (aFillLength / 4) rounding down)
		repeat while (aTabCount > 0)
			(aComment's appendString:tabText)
			set aTabCount to aTabCount - 1
		end repeat
		
		set aIntegerValue to 2 ^ aShift
		(aComment's appendFormat_("// %@", aIntegerValue))
		(aSuffix's appendString:aComment)
	end if
	
	return aSuffix
end createSuffixForIndex:

on splitString:aString
	set aSplitCharSet to NSMutableCharacterSet's new()
	set aNewLineSet to NSCharacterSet's newlineCharacterSet()
	aSplitCharSet's formUnionWithCharacterSet:aNewLineSet
	set aCommaCharSet to NSCharacterSet's characterSetWithCharactersInString:","
	aSplitCharSet's formUnionWithCharacterSet:aCommaCharSet
	set aSplitString to (aString's componentsSeparatedByCharactersInSet:aSplitCharSet)
	
	set aCleanedArray to (NSMutableArray's new())
	repeat with aLine in aSplitString
		if ((aLine is not "") and (aLine is not missing value)) then
			set aCleanLine to (my cleanAllWhiteSpaceInText:aLine)
			(aCleanedArray's addObject:aCleanLine)
		end if
	end repeat
	return aCleanedArray
end splitString:


-- CLEAN WHITESPACE (ALL)
on cleanAllWhiteSpaceInText:aText
	set aString to (NSString's stringWithString:aText)
	set aPattern to (NSString's stringWithString:"(\\s+){2}")
	set aDirtyString to (aString's ¬
		stringByReplacingOccurrencesOfString:aPattern withString:" " options:(NSRegularExpressionSearch) range:(current application's NSMakeRange(0, aString's |length|)))
	set aCharSet to NSCharacterSet's whitespaceCharacterSet()
	set aCleanString to (aDirtyString's stringByTrimmingCharactersInSet:aCharSet)
	return aCleanString
end cleanAllWhiteSpaceInText:

on parseOptionsForModFlags:modKeysFlags
	set hasCommand to ((modFlags div NSCommandKeyMask) mod 2) = 1
	set hasOption to ((modFlags div NSAlternateKeyMask) mod 2) = 1
	set hasControl to ((modFlags div NSControlKeyMask) mod 2) = 1
	set hasShift to (((modFlags) div (get NSShiftKeyMask)) mod 2) = 1
	
	if hasShift then set addBitValueComment to true
	if (hasOption or hasCommand) then
		set useBitShift to false
		set addBitValueComment to false
		if hasCommand then set useOffset to true
	end if
	
	if (useOffset) then
		set theResult to display dialog ¬
			"Enter Your First Value" default answer (startOffset as text) ¬
			
		set startOffset to (text returned of theResult) as integer
	end if
end parseOptionsForModFlags:

see separate replies below for examples of running the different options

results with useBitShift mode (Default)

	Checked_None = 0,
	Checked_Whitespace = 1 << 0,
	Checked_EpisodeID = 1 << 1,
	Checked_CatalogNo = 1 << 2,
	Checked_Composer = 1 << 3,
	Checked_Label = 1 << 4,
	Checked_Rating = 1 << 5,
	Checked_Show = 1 << 6,
	Checked_Comments = 1 << 7,
	Checked_Genre = 1 << 8,
	Checked_MultiArtists = 1 << 9,
	Checked_Quality = 1 << 10,
	Checked_Dupes = 1 << 11

Notice the last line does NOT add a comma

results with addBitValueComment mode (ShiftKeyMask)

	Checked_None = 0,
	Checked_Whitespace = 1 << 0,					// 1
	Checked_EpisodeID = 1 << 1,					// 2
	Checked_CatalogNo = 1 << 2,					// 4
	Checked_Composer = 1 << 3,						// 8
	Checked_Label = 1 << 4,						// 16
	Checked_Rating = 1 << 5,						// 32
	Checked_Show = 1 << 6,							// 64
	Checked_Comments = 1 << 7,						// 128
	Checked_Genre = 1 << 8,						// 256
	Checked_MultiArtists = 1 << 9,					// 512
	Checked_Quality = 1 << 10,						// 1024
	Checked_Dupes = 1 << 11						// 2048

– FOR ABOVE you can see in the code I’m trying to work out balancing the tabs
– when I paste this into XCode it balances properly for me
– play with the lengthPad for different results

results with useBitShift off mode (AlternateKeyMask)

	Checked_None,
	Checked_Whitespace,
	Checked_EpisodeID,
	Checked_CatalogNo,
	Checked_Composer,
	Checked_Label,
	Checked_Rating,
	Checked_Show,
	Checked_Comments,
	Checked_Genre,
	Checked_MultiArtists,
	Checked_Quality,
	Checked_Dupes

SIMILIAR TO Comma List EXT splicing but adds commas (except last line)

results with useOffset mode (CommandKeyMask) entering 5 in dialog

	Checked_None = 5,
	Checked_Whitespace = 6,
	Checked_EpisodeID = 7,
	Checked_CatalogNo = 8,
	Checked_Composer = 9,
	Checked_Label = 10,
	Checked_Rating = 11,
	Checked_Show = 12,
	Checked_Comments = 13,
	Checked_Genre = 14,
	Checked_MultiArtists = 15,
	Checked_Quality = 16,
	Checked_Dupes = 17