Haha, anyway, I'm just sharing it here:
Save "o()" function objects in ".ini" files! (Click here)
o(Funcion) _VS_ Built-in Object - Speed Test (Click here)
v1.4 (Click here)
v1.3 (Click here)
v1.2 (Click here)
v1.1 (Click here)
v1.0 (below):
simple examples, Defining, Get, InsertingAt, RemovingAt:
Code: Select all
;uncomment the "Local" line inside the function if you use AutoHotKey v1.1.27+
;Force all variables in the function to be "Local" vars (with no exceptions)
;"Force-local" mode (only supported on AutoHotKey v1.1.27+)
;the function was tested in AutoHotKey 1.1.23.05
O(Test, "x", , "=", "xxx")
O(Test, "y", , "=", "yyy")
O(Test, "z", , "=", "zzz")
O(Test, "xyz", , "=", "xxx`r`nyyy`r`nzzz")
O(Test, "#@#!", , "=", "#@#! _ #@#! _ #@#!")
O(Test, "Type", "House1", "=", "H T 111")
O(Test, "Size", "House1", "=", "H S 111")
O(Test,"Color", "House1", "=", "H C 111")
O(Test, "Type", "House2", "=", "H T 222")
O(Test, "Size", "House2", "=", "H S 222")
O(Test,"Color", "House2", "=", "H C 222")
O(Test, "Type", "House3", "=", "H T 333")
O(Test, "Size", "House3", "=", "H S 333")
O(Test,"Color", "House3", "=", "H C 333")
O(Test, "Type", "House4", "=", "H T 444")
O(Test, "Size", "House4", "=", "H S 444")
O(Test,"Color", "House4", "=", "H C 444")
O(Test, "Type", "House5", "=", "H T 555")
O(Test, "Size", "House5", "=", "H S 555")
O(Test,"Color", "House5", "=", "H C 555")
O(Test, "Type", "House6", "=", "H T 666")
O(Test, "Size", "House6", "=", "H S 666")
O(Test,"Color", "House6", "=", "H C 666")
O(Test, "Type", "House10", "=", "H T 101010")
O(Test, "Size", "House10", "=", "H S 101010")
O(Test,"Color", "House10", "=", "H C 101010")
O(Test, , "House5", "DelSection") ;Delete Section ("House6" section will be made "House5" section, and so on ...!)
O(Test, "Type", "House2", "<=", "H T 777") ;"<=" = "InsertAt" section (the previous "House2" section will be made "House3" section, and so on ...!)
O(Test, "Size", "House2", "=", "H S 777")
O(Test,"Color", "House2", "=", "H C 777")
;__
gui, add, edit, w600 h400 +HwndEditControlId,
ControlSetText , , % Test, % "ahk_id" EditControlId
gui, show
;__
msgbox, % ""
. O(Test, "x") " - " O(Test, "y") " - " O(Test, "z") "`n`n"
. O(Test, "xyz") "`n"
. "`n"
. O(Test, "#@#!") "`n"
. "`n"
. O(Test, "Type", "House1") " - " O(Test, "Size", "House1") " - " O(Test, "Color", "House1") "`n"
. O(Test, "Type", "House2") " - " O(Test, "Size", "House2") " - " O(Test, "Color", "House2") "`n"
. O(Test, "Type", "House3") " - " O(Test, "Size", "House3") " - " O(Test, "Color", "House3") "`n"
. O(Test, "Type", "House4") " - " O(Test, "Size", "House4") " - " O(Test, "Color", "House4") "`n"
. O(Test, "Type", "House5") " - " O(Test, "Size", "House5") " - " O(Test, "Color", "House5") "`n"
. O(Test, "Type", "House6") " - " O(Test, "Size", "House6") " - " O(Test, "Color", "House6") "`n"
. O(Test, "Type", "House7") " - " O(Test, "Size", "House7") " - " O(Test, "Color", "House7") "`n"
. O(Test, "Type", "House8") " - " O(Test, "Size", "House8") " - " O(Test, "Color", "House8") "`n"
. O(Test, "Type", "House9") " - " O(Test, "Size", "House9") " - " O(Test, "Color", "House9") "`n"
. O(Test, "Type", "House10") " - " O(Test, "Size", "House10") " - " O(Test, "Color", "House10") "`n"
return
guiclose: ;__________________________ Gui Close ___________________________
exitapp
O(ByRef Var, Key := "", Section := "", Task := "", Value := "") ;__________________ SimpleObject(Function) - v1.0 _________________________
{
;Local ;uncomment this line if you use AutoHotKey v1.1.27+
;Force all variables in this function to be "Local" vars (with no exceptions)
;"Force-local" mode (only supported on AutoHotKey v1.1.27+)
;this function was tested in AutoHotKey 1.1.23.05
;Local AnyVariable ;(Not Recommended) this line would switch the function mode from "assume-Local" to "assume-Global" (makes all variables global by default)
Key := RegExReplace(Key, "#", "#_")
Value := RegExReplace(Value, "#", "#_")
Section := RegExReplace(Section, "#", "#_")
KeyEsc2 := "\Q" RegExReplace(Key, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
KeyEsc3 := RegExReplace(Key, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
ValueEsc2 := "\Q" RegExReplace(Value, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
ValueEsc3 := RegExReplace(Value, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
SectionEsc2 := "\Q" RegExReplace(Section, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
SectionEsc3 := RegExReplace(Section, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
;_
FindSection := "s)#" SectionEsc2 "#@(.*?)#End#!"
if RegExMatch(Var, FindSection, Match)
SectionExist := "1"
SectionContent := Match1
;_
FindKey := "s)#" KeyEsc2 "#( | )*?=( | )*?#(.*?)#(?!_)"
;#(?!_), match an "#" without "_" at its right!
;( | ), Space or Tab
if RegExMatch(SectionContent, FindKey, Match)
KeyExist := "1"
KeyValue := Match3
;_
SectionName := RegExReplace(Section, "\d+$") ;if exist, remove the sequence of numbers at the end
RegExMatch(Section, "\d+$", Match) ;if exist, match the sequence of numbers at the end
SectionIndex := Match
SectionNameEsc2 := "\Q" RegExReplace(SectionName, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
SectionNameEsc3 := RegExReplace(SectionName, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
if (Task = "<=" and SectionIndex != "" and SectionIndex > 0) ;"=>" means "Insert at" Section Index (Example: Insert at "Col1" section, the previous "Col1" section is moved to "col2", the previous "Col2" is moved to "col3", and so on ...!)
{
if (SectionExist != "1") ;means that insertion Section Index point does not exist
Task := "=" ;Forces the new section to be created anyway
else
{
Var := RegExReplace(Var, FindSection, "#" SectionEsc3 "#@`r`n#" KeyEsc3 "# = #" ValueEsc3 "#`r`n#End#!`r`n`r`n$0")
UpdateSectionIndex := "1"
}
}
if (Task = "DelSection")
{
Var := RegExReplace(Var, FindSection "`r`n`r`n") ;Delete section
if (SectionIndex != "" and SectionIndex > 0)
UpdateSectionIndex := "1"
}
if (UpdateSectionIndex = "1")
{
FoundPos := 1
MatchLenght := 0
Count := 1
loop
{
FoundPos := RegExMatch(Var, "#" SectionNameEsc2 "(\d+)#@", Match, FoundPos + MatchLenght)
if (FoundPos = 0 or FoundPos = "")
break
else
{
MatchLenght := StrLen(Match)
IndexFound := Match1
if (IndexFound = 0)
Continue ;"Continue", Skips the rest of the current loop iteration and begins a new one.
Var := RegExReplace(Var, "#" SectionNameEsc2 "(\d+)#@", "#" SectionNameEsc3 Count "#@", , 1, FoundPos)
MatchLenght := StrLen(SectionName) + StrLen(Count) + 3 ;the "+ 3" is for "##@"
Count++
}
}
}
if (Task == "") ;if blank, "Get" key's value
{
;return, SectionContent
KeyValue := RegExReplace(KeyValue, "#_", "#")
return, KeyValue
}
else if (Task = "=")
{
if (SectionExist = "1")
{
if (KeyExist = "1")
{
SectionContent := RegExReplace(SectionContent, FindKey, "#" KeyEsc3 "# = #" ValueEsc3 "#")
}
else
{
SectionContent .= "#" Key "# = #" Value "#`r`n"
}
EditedSection := "#" Section "#@" SectionContent "#End#!"
EditedSection := RegExReplace(EditedSection, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
Var := RegExReplace(Var, FindSection, EditedSection)
}
else
{
if (SectionIndex != "" and SectionIndex > 1)
{
if !RegExMatch(Var, "s)#" SectionNameEsc2 "1#@(.*?)#End#!")
var .= "#" SectionName "1#@`r`n#End#!`r`n`r`n"
loop, % SectionIndex
{
if (a_index = SectionIndex)
Var := RegExReplace(Var, "s)#" SectionNameEsc2 a_index - 1 "#@(.*?)#End#!", "$0`r`n`r`n#" SectionNameEsc3 a_index "#@`r`n#" KeyEsc3 "# = #" ValueEsc3 "#`r`n#End#!")
else if !RegExMatch(Var, "s)#" SectionNameEsc2 a_index "#@(.*?)#End#!")
Var := RegExReplace(Var, "s)#" SectionNameEsc2 a_index - 1 "#@(.*?)#End#!", "$0`r`n`r`n#" SectionNameEsc3 a_index "#@`r`n#End#!")
}
;msgbox, % SectionName " - " SectionIndex
}
else
{
Var.= "#" Section "#@`r`n#" Key "# = #" Value "#`r`n#End#!`r`n`r`n"
}
}
}
}
Code: Select all
;uncomment the "Local" line inside the function if you use AutoHotKey v1.1.27+
;Force all variables in the function to be "Local" vars (with no exceptions)
;"Force-local" mode (only supported on AutoHotKey v1.1.27+)
;the function was tested in AutoHotKey 1.1.23.05
;"##@" is the blank section (Which is the main section)
LV =
(join`r`n
##@
#Test#=#Type#
#Type#=#T #_#_ #_@ #_! MainSection#
#Options# = #O MainSection#
#Col1# = #Col1 MainSection#
#End#!
#Col1#@
#Test#=#Type#
#Type# = #T1#
#Options# = #O1#
#Col2# = #Col2 111#
#End#!
#Col2#@
#Test#=#Type#
#Type# = #T2#
#Options# = #O2#
#Col3# = #Col3 222#
#End#!
#Col3#@
#Test#=#Type#
#Type# = #T3#
#Options# = #O3#
#Col4# = #Col4 333#
#End#!
#End#@
#Test#=#Type#
#Type# = #T End#
#Options# = #O End#
#Col5# = #Col5 End#
#End#!
) ;Extra "`r`n`r`n" at the end just for better testing
SimpleObject(LV, "Test" , , "=", " Value #Col2#@ - #End#! Value ")
SimpleObject(LV, " Key #Col2#@ - #End#! Key ", , "=", "Test2")
SimpleObject(LV, "Test", "NewSection", "=", "Type")
SimpleObject(LV, "type", "NewSection", "=", "T NewSection")
SimpleObject(LV, "Option", "NewSection", "=", "O NewSection")
SimpleObject(LV, "type", "NewSection", "=", "T NewSection - EEEE")
SimpleObject(LV, "Test", "NewSection5", "=", "Type")
SimpleObject(LV, "type", "NewSection5", "=", "T NewSection5")
SimpleObject(LV, "Option", "NewSection5", "=", "O NewSection5")
SimpleObject(LV, "type", "NewSection5", "=", "T NewSection5 - EEEE")
SimpleObject(LV, "Test", "NewSection0", "=", "NewSection0")
SimpleObject(LV, "Test", "#Col7#@", "=", "Type #Col7#@")
SimpleObject(LV, "Test", "Col7", "=", "Type")
SimpleObject(LV, "Type", "Col7", "=", "T7")
SimpleObject(LV, "Test", "za1", "=", "Type")
SimpleObject(LV, "Test", "ta1", "=", "Type")
SimpleObject(LV, "Test", "yu0", "=", "Type")
SimpleObject(LV, "Test", "10", "=", "Index Only Test 10")
SimpleObject(LV, "Test", "House23Floor11", "=", "House Test 11")
SimpleObject(LV, "Test", "NewSection", "=>", "Insert Test NewSection") ;this will be ignored because there is no number in the end
SimpleObject(LV, "Test", "NewSection0", "=>", "Insert Test NewSection0") ;this will be ignored because number at the end is 0
SimpleObject(LV, "Test", "NewSection1", "=>", "Insert Test NewSection1")
SimpleObject(LV, "Test", "NewSection4", "=>", "Insert Test NewSection4")
SimpleObject(LV, "Test", "NewSection10", "=>", "Insert Test NewSection10") ;"NewSection10" section does not exist, but it will be created anyway
SimpleObject(LV, , "5", "DelSection")
SimpleObject(LV, , "House23Floor10", "DelSection")
;SimpleObject(LV, "Test", "Col467", "=", "Type")
;SimpleObject(LV, "Test", "94", "=", "Type")
;SimpleObject(LV, "Test", "8999", "=", "Type")
gui, add, edit, w600 h400 +HwndEditControlId,
ControlSetText , , % LV, % "ahk_id" EditControlId
gui, show
;msgbox, % SimpleObject(LV, "") "`n`n"
;msgbox, % SimpleObject(LV, "", "Col1") "`n`n"
;msgbox, % SimpleObject(LV, "", "Col2") "`n`n"
;msgbox, % SimpleObject(LV, "", "Col3") "`n`n"
;msgbox, % SimpleObject(LV, "", "Col4") "`n`n"
;msgbox, % SimpleObject(LV, "", "End") "`n`n"
msgbox, % SimpleObject(LV, "Type") "`n`n" ;get "Type" value from blank section (Which is the main section)
msgbox, % SimpleObject(LV, "Type", "Col1") "`n`n" ;get "Type" value from "Col1" section
msgbox, % SimpleObject(LV, "Type", "Col2") "`n`n" ;get "Type" value from "Col2" section
msgbox, % SimpleObject(LV, "Type", "Col3") "`n`n" ;and so on ...!
msgbox, % SimpleObject(LV, "Type", "Col4") "`n`n"
msgbox, % SimpleObject(LV, "Type", "End") "`n`n"
msgbox, % SimpleObject(LV, "Type", "Col7") "`n`n"
return
guiclose: ;__________________________ Gui Close ___________________________
exitapp
SimpleObject(ByRef Var, Key := "", Section := "", Task := "", Value := "") ;__________________ SimpleObject(Function) - v1.0 _________________________
{
;Local ;uncomment this line if you use AutoHotKey v1.1.27+
;Force all variables in this function to be "Local" vars (with no exceptions)
;"Force-local" mode (only supported on AutoHotKey v1.1.27+)
;this function was tested in AutoHotKey 1.1.23.05
;Local AnyVariable ;(Not Recommended) this line would switch the function mode from "assume-Local" to "assume-Global" (makes all variables global by default)
Key := RegExReplace(Key, "#", "#_")
Value := RegExReplace(Value, "#", "#_")
Section := RegExReplace(Section, "#", "#_")
KeyEsc2 := "\Q" RegExReplace(Key, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
KeyEsc3 := RegExReplace(Key, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
ValueEsc2 := "\Q" RegExReplace(Value, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
ValueEsc3 := RegExReplace(Value, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
SectionEsc2 := "\Q" RegExReplace(Section, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
SectionEsc3 := RegExReplace(Section, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
;_
FindSection := "s)#" SectionEsc2 "#@(.*?)#End#!"
if RegExMatch(Var, FindSection, Match)
SectionExist := "1"
SectionContent := Match1
;_
FindKey := "s)#" KeyEsc2 "#( | )*?=( | )*?#(.*?)#(?!_)"
;#(?!_), match an "#" without "_" at its right!
;( | ), Space or Tab
if RegExMatch(SectionContent, FindKey, Match)
KeyExist := "1"
KeyValue := Match3
;_
SectionName := RegExReplace(Section, "\d+$") ;if exist, remove the sequence of numbers at the end
RegExMatch(Section, "\d+$", Match) ;if exist, match the sequence of numbers at the end
SectionIndex := Match
SectionNameEsc2 := "\Q" RegExReplace(SectionName, "\\E", "\E\\E\Q") "\E" ;Escaped Var to be used with "RegExMatch" and "RegExReplace" second parameters! ("\\" represents one literal "\")
SectionNameEsc3 := RegExReplace(SectionName, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
if (Task = "=>" and SectionIndex != "" and SectionIndex > 0) ;"=>" means "Insert at" Section Index (Example: Insert at "Col1" section, the previous "Col1" section is moved to "col2", the previous "Col2" is moved to "col3", and so on ...!)
{
if (SectionExist != "1") ;means that insertion Section Index point does not exist
Task := "=" ;Forces the new section to be created anyway
else
{
Var := RegExReplace(Var, FindSection, "#" SectionEsc3 "#@`r`n#" KeyEsc3 "# = #" ValueEsc3 "#`r`n#End#!`r`n`r`n$0")
UpdateSectionIndex := "1"
}
}
if (Task = "DelSection")
{
Var := RegExReplace(Var, FindSection "`r`n`r`n") ;Delete section
if (SectionIndex != "" and SectionIndex > 0)
UpdateSectionIndex := "1"
}
if (UpdateSectionIndex = "1")
{
FoundPos := 1
MatchLenght := 0
Count := 1
loop
{
FoundPos := RegExMatch(Var, "#" SectionNameEsc2 "(\d+)#@", Match, FoundPos + MatchLenght)
if (FoundPos = 0 or FoundPos = "")
break
else
{
MatchLenght := StrLen(Match)
IndexFound := Match1
if (IndexFound = 0)
Continue ;"Continue", Skips the rest of the current loop iteration and begins a new one.
Var := RegExReplace(Var, "#" SectionNameEsc2 "(\d+)#@", "#" SectionNameEsc3 Count "#@", , 1, FoundPos)
MatchLenght := StrLen(SectionName) + StrLen(Count) + 3 ;the "+ 3" is for "##@"
Count++
}
}
}
if (Task == "") ;if blank, "Get" key's value
{
;return, SectionContent
KeyValue := RegExReplace(KeyValue, "#_", "#")
return, KeyValue
}
else if (Task = "=")
{
if (SectionExist = "1")
{
if (KeyExist = "1")
{
SectionContent := RegExReplace(SectionContent, FindKey, "#" KeyEsc3 "# = #" ValueEsc3 "#")
}
else
{
SectionContent .= "#" Key "# = #" Value "#`r`n"
}
EditedSection := "#" Section "#@" SectionContent "#End#!"
EditedSection := RegExReplace(EditedSection, "\$", "$$$$") ;Escaped Var to be used with "RegExReplace" third parameter! ("$$" represents one literal "$")
Var := RegExReplace(Var, FindSection, EditedSection)
}
else
{
if (SectionIndex != "" and SectionIndex > 1)
{
if !RegExMatch(Var, "s)#" SectionNameEsc2 "1#@(.*?)#End#!")
var .= "#" SectionName "1#@`r`n#End#!`r`n`r`n"
loop, % SectionIndex
{
if (a_index = SectionIndex)
Var := RegExReplace(Var, "s)#" SectionNameEsc2 a_index - 1 "#@(.*?)#End#!", "$0`r`n`r`n#" SectionNameEsc3 a_index "#@`r`n#" KeyEsc3 "# = #" ValueEsc3 "#`r`n#End#!")
else if !RegExMatch(Var, "s)#" SectionNameEsc2 a_index "#@(.*?)#End#!")
Var := RegExReplace(Var, "s)#" SectionNameEsc2 a_index - 1 "#@(.*?)#End#!", "$0`r`n`r`n#" SectionNameEsc3 a_index "#@`r`n#End#!")
}
;msgbox, % SectionName " - " SectionIndex
}
else
{
Var.= "#" Section "#@`r`n#" Key "# = #" Value "#`r`n#End#!`r`n`r`n"
}
}
}
}