Thanks to the newly supported assume static this feature is actually useful.
This requires Autohotkey version 1.0.48.00 or newer.
Description
The whole idea about this is to create something similar to olegbl's
AHKArray without having to deal with all that hexing and delimiters and such. To give programmers a bit of abstraction it stores all items within the local scope of the AHKList function as normal autohotkey arrays (dynamically named variables).
While this could possibly create many variables in the local scope of the AHKList function. Once an item is removed from the list all items after the one deleted are moved forward and the last variable is set blank to save memory.
The programmer may access lists he creates by using a set of commands to the AHKList function. Currently Accepted commands are:
- Add
- InsertBefore
- Get
- GetIndex
- Remove
- Print
- Pop
- RemItem
- WhatsInside
- Set
Documentation
A more detailed documentation can be found here:
http://philzerull.com/#AHKList
I plan on adding new features as time goes on.
I think a sorting feature will be nice. But please let me know what else might be useful to add to it.
Code
Code:
AHKList(listname, command="add", subcommand1="", subcommand2="", Debug="1") {
static
returnit := 1
if (command = "add") {
%listname%0 ++
Curcount := %Listname%0
%listname%%Curcount% := Subcommand1
returnit := curcount
}
else if (command = "InsertBefore") {
if (subcommand2 = "") {
if (Debug)
Msgbox Error with command: %Command%`nSubcommand2 is Blank
returnit := 0
}
if (returnit) { ;preform only if no error has occured thusfar
Curcount := %Listname%0
if (Subcommand2 > Curcount) {
if (Debug)
Msgbox Error with command: %Command%`n%listname% index: Subcommand2 out of range.`nThe index you specified is %Subcommand2%.`nIt should be no larger than %Curcount%.
returnit := 0
}
if (Subcommand2 <= 0) {
if (Debug)
Msgbox Error with command: %Command%`n%listname% index: Subcommand2 out of range.`nThe index you specified is 0.`nIt should be at least 1.
returnit := 0
}
if (returnit) { ;preform only if no error has occured thusfar
loop % Curcount - Subcommand2 + 2 {
moveto := curcount - (a_index - 1) + 1
movefrom := curcount - (a_index - 1)
%Listname%%moveto% := %Listname%%movefrom%
}
%listname%0 ++
%Listname%%moveto% := Subcommand1
returnit := %listname%0
}
}
}
else if (command = "Get") {
curcount := %listname%0
returnit = 1
if (Subcommand1="")
Subcommand1 = 0
if (subcommand1 < 0) {
if (debug)
msgbox Error with command: %Command%`nSubcommand1 must be greater'nthan or equal to zero.
returnit := 0
}
if (Subcommand1 > Curcount) {
if (Debug)
Msgbox Error with command: %Command%`n%listname% index: Subcommand1 out of range.`nThe index you specified is %Subcommand1%.`nIt should be no larger than %Curcount%.
returnit := 0
}
if (returnit)
returnit := %listname%%Subcommand1%
}
else if (command = "GetIndex") {
loop % %listname%0 {
if (Subcommand1 = %listname%%A_index%) {
returnit := A_index
break
}
else {
returnit := 0
}
}
if (debug) AND !(returnit)
Msgbox Error with command: %Command%`n%Subcommand1% does not exist within %listname%
}
else if (command = "Remove") {
curcount := %listname%0
if (subcommand1 = "") {
if (debug)
Msgbox Error with command: %Command%`nSubcommand1 is expected but missing.
returnit := 0
}
if (subcommand1 < 0) {
if (debug)
msgbox Error with command: %Command%`nSubcommand1 must be greater`nthan or equal to zero.
returnit := 0
}
if (returnit) AND ((subcommand1 > curcount) OR !(subcommand1)) {
if (debug)
Msgbox Error with command: %Command%`nSubcommand1 is out of range.`nThe value you specified is %subcommand1%.`nIt should be between 1 and %curcount%.
returnit := 0
}
if (returnit) {
loop % %listname%0 - subcommand1 {
moveto := subcommand1 + (a_index - 1)
movefrom := subcommand1 + (a_index - 1) + 1
%Listname%%moveto% := %Listname%%movefrom%
}
AHKList(listname, "Set", %listname%0)
%listname%0 --
;I chose not to blank out the old last index because if I could declare static like i do
;global then the user could not access the old last index anyway.
}
}
else if (command = "Print") {
returnit := ""
loop % %listname%0 {
returnit = % returnit A_index " " %Listname%%a_index% "`n"
}
if (debug)
msgbox %returnit%
}
else if (command = "Pop") {
dummy := AHKList(listname, "Get", AHKList(listname, "Get"))
AHKList(listname, "Remove", AHKList(listname, "Get"))
returnit := dummy
}
else if (command = "RemItem") {
if (subcommand1 = "") {
if (debug)
Msgbox Error with command: %Command%`nSubcommand1 is expected but missing.
returnit := 0
}
if (returnit) {
dummy := subcommand2 = "" ? 1 : subcommand2
if (dummy < 0 ) {
dummy = 0
loop % AHKList(listname, "get") {
if (AHKList(listname, "get", a_index + dummy) = subcommand1) {
AHKList(listname, "remove", a_index + dummy)
dummy --
}
}
}
else {
loop % AHKList(listname, "get") {
if (dummy = 0)
break
if (AHKList(listname, "get", a_index - dummy <= 0 ? 1 : a_index - dummy) = subcommand1) {
AHKList(listname, "remove", a_index - dummy <= 0 ? 1 : a_index - dummy)
dummy --
}
}
}
}
}
else if (command = "whatsinside") {
listvars
msgbox Close this to continue the script
}
else if (command = "set") {
if (Subcommand1="")
Subcommand1 = 0
else if (subcommand1 < 0) {
if (debug)
msgbox Error with command: %Command%`nSubcommand1 must be greater'nthan or equal to zero.
returnit := 0
}
else if (Subcommand1 > Curcount) {
if (Debug)
Msgbox Error with command: %Command%`n%listname% index: Subcommand1 out of range.`nThe index you specified is %Subcommand1%.`nIt should be no larger than %Curcount%.
returnit := 0
}
%listname%%Subcommand1% := subcommand2
}
return % returnit
}
ExamplesCode:
;make a new list called fruit and add a banana to the list
ahklist("Fruit", "add", "Banana")
;to save time typing I'll define a shortcut function
;Please not that ahklist always requires the listname command
fruit(command, subcom1="", subcom2="", debug="1") {
return % ahklist("Fruit", command, subcom1, subcom2, debug)
}
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
;Add a whole bunch of fruit to the mix
listvars
msgbox See There are no variables in the global scope
fruit("Whatsinside")
;The variables are all on the local scope
fruit("set", 4, "Mango")
fruit("set", 5)
;Change some values
fruit("print")
fruit("insertbefore", "This is before a mango", 4)
;insert something before the mango. This puts Mango in the fourth location.
msgbox % fruit("get", 5) "`nSee the " fruit("getindex", "Mango") "th place is a mango."
fruit("remove", 1) ; So i was hungry
; i removed a banana and ate it.
fruit("add", "bubble")
msgbox % "I popped a " fruit("pop")
;Ok so I'll eat the first two bananas
fruit("remitem", "Banana", 2)
fruit("print")
;guess the oranges went bad better get rid of them all.
fruit("remitem", "Orange", -1)
fruit("print")
Please feel free to let me know what you think.
I accept any comments, questions, queries, and qualms.
I am wondering what might be the most user friendly way to store collections of items in AHK.