Code style

Code style

; 初始化class_Vim
vim_Init:
    #UseHook
    SetKeyDelay, -1
return

; 用于热键映射
vim_Key:
    vim.Key()
return

; 用于热键超时
vim_TimeOut:
    vim.IsTimeOut()
return

; 用于Count计数
Internal:
    __v.SetPlugin("Internal", "Array", "0.1", "内置插件")
    __v.SetAction("<1>", "Number 1")
    __v.SetAction("<2>", "Number 2")
    __v.SetAction("<3>", "Number 3")
    __v.SetAction("<4>", "Number 4")
    __v.SetAction("<5>", "Number 5")
    __v.SetAction("<6>", "Number 6")
    __v.SetAction("<7>", "Number 7")
    __v.SetAction("<8>", "Number 8")
    __v.SetAction("<9>", "Number 9")
    __v.SetAction("<0>", "Number 0")
    __v.SetAction("<>", "空操作")
    __v.SetAction("<Pass>", "空操作")
    __v.SetAction("<Default>", "恢复默认")
    __v := ""
return

<1>:
<2>:
<3>:
<4>:
<5>:
<6>:
<7>:
<8>:
<9>:
<0>:
<>:
<Pass>:
<Default>:
return

Class_vim()
{
    global __v
    GoSub, Vim_Init
    __v := v := new __vim
    __v.LoadPlugin("Internal")
    return v
}

GetLastAction()
{
    global __vimLastAction
    return __vimLastAction
}

ShowInfo()
{
    Global vim
    obj := vim.GetMore(true)
    winObj := vim.GetWin(vim.LastFoundWin)
    if winObj.Count
        np .= winObj.Count
    Loop, % obj.MaxIndex()
    {
        act := vim.GetAction(obj[A_Index]["Action"])
        np .= obj[A_Index]["key"] "`t" act.Comment "`n"
        If (A_Index = 1)
            np .= "=====================`n"
    }
    MouseGetPos, posx, posy, A
    posx += 60
    posy += 60
    Tooltip, %np%, %posx%, %posy%
}

HideInfo()
{
    Tooltip
}

; 定义数据结构
; Class __vim {{{1
Class __vim
{
    __new()
    {
        this.PluginList := []
        this.WinList    := []
        this.WinInfo    := []
        this.ActionList := []
        this.ActionFromPlugin := []
        this.ExcludeWinList :=[]
        this.winGlobal  := new __win
        this.ErrorCode  := 0
        tihs.ActionFromPluginName := ""
        this.LastFoundWin := ""
    }

    ; LoadPlugin(PluginName) {{{2
    ; 用于注册插件
    LoadPlugin(PluginName)
    {
        If this.PluginList[PluginName]
            return this.PluginList[PluginName]
        p := new __Plugin(PluginName)
        this.PluginList[PluginName] := p
        back := this.ActionFromPluginName
        this.ActionFromPluginName := PluginName
        p.CheckSub()
        If p.Error
        {
            msgbox load plugin "%PluginName%" error
            this.ActionFromPluginName := back
        }
    }

    ; SetPlugin(PluginName, Author="", Ver="", Comment="") {{{2
    ; 设置Plugin信息
    SetPlugin(PluginName, Author="", Ver="", Comment="")
    {
        p := this.PluginList[PluginName]
        p.Author := Author
        p.Ver := Ver
        p.Comment := Comment
    }

    ; GetPlugin(PluginName) {{{2
    ; 获取Plugin信息
    GetPlugin(PluginName)
    {
        return this.PluginList[PluginName]
    }

    ; Comment(action, desc, complex=1) {{{2
    ; 兼容老版本的vimcore.ahk
    Comment(action, desc="", complex=1)
    {
        act := this.SetAction(Action, Desc)
        If not complex ; 不允许多次运行
            act.SetMaxTimes(1)
      return act
    }

    ; SetAction(Name, Comment) {{{2
    ; 用于为Action(动作)进行注释
    SetAction(Name, Comment="")
    {
        If this.ActionList[Name]
            ra := This.ActionList[Name]
        Else
            ra := This.ActionList[Name] := new __Action(Name, Comment)
        This.ActionFromPlugin[Name] := this.ActionFromPluginName
        return ra
    }

    ; GetAction(Name) {{{2
    ; 获取Action的信息
    GetAction(Name)
    {
        return this.ActionList[Name]
    }

    ; SetWin(winName, class, filepath, title) {{{2
    ; 添加win成员
    SetWin(winName, class, filepath="", title="")
    {
        If this.WinList[winName]
            rw := this.WinList[winName]
        Else
            rw := this.WinList[winName] := new __win(class, filepath, title)
        this.WinInfo["class`t"class]       := winName
        this.WinInfo["filepath`t"filepath] := winName
        this.WinInfo["title`t"title]       := winName
        return rw
    }

    ; GetWin(winName) {{{2
    GetWin(winName="")
    {
        If strlen(winName)
            return this.WinList[winName]
        Else
            return this.winGlobal
    }

    ; CheckWin() {{{2
    CheckWin()
    {
        /*
        WinGetTitle, t, A
        If Strlen(winName:=this.WinInfo["title`t"t])
            return winName
        */

        WinGet, f, ProcessName, A
        If Strlen(winName:=this.WinInfo["filepath`t"f])
            return winName
        WinGetClass, c, A
        If Strlen(winName:=this.WinInfo["class`t"c])
            return winName
    }

    ; mode(mode, win="") {{{2
    ; 兼容老版本的vimcore.ahk
    mode(mode, win="")
    {
        If not IsObject(this.GetWin(win))
            this.SetWin(win, win)
        return this.SetMode(mode, win)
    }

    ; SetMode(modeName, winName) {{{2
    SetMode(modeName, winName="")
    {
        winObj := This.GetWin(winName)
        return winObj.ChangeMode(modeName)
    }

    ; SetModeFunction(func, modeName, winName="") {{{2
    SetModeFunction(func, modeName, winName="")
    {
        winObj := This.GetWin(winName)
        modeObj := winObj.modeList[modeName]
        modeObj.modeFunction := func
    }

    ; GetMode(winName) {{{2
    ; 获取指定win中当前的模式
    GetMode(winName="")
    {
        winObj := This.GetWin(winName)
        return winObj.modeList[winobj.ExistMode()]
    }

    ; GetInputState {{{2
    GetInputState(WinTitle="A")
    {
        ControlGet, hwnd, HWND, , , %WinTitle%
        if (A_Cursor = "IBeam")
            return 1
        if (WinActive(WinTitle))
        {
            ptrSize := !A_PtrSize ? 4 : A_PtrSize
            VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
            NumPut(cbSize, stGTI, 0, "UInt")   ;   DWORD   cbSize;
            hwnd := DllCall("GetGUIThreadInfo", Uint, 0, Uint, &stGTI)
                             ? NumGet(stGTI, 8+PtrSize, "UInt") : hwnd
        }
        return DllCall("SendMessage"
            , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint, hwnd)
            , UInt, 0x0283  ;Message : WM_IME_CONTROL
            , Int, 0x0005  ;wParam  : IMC_GETOPENSTATUS
            , Int, 0)      ;lParam  : 0
    }

    ; BeforeActionDo(Function, winName="") {{{2
    BeforeActionDo(Function, winName="")
    {
        winObj  := this.GetWin(winName)
        winObj.BeforeActionDoFunc := Function
    }

    ; AfterActionDo(Function, winName="") {{{2
    AfterActionDo(Function, winName="")
    {
        winObj := this.GetWin(winName)
        winObj.AfterActionDoFunc := Function
    }

    ; SetMaxCount(Int, winName) {{{2
    SetMaxCount(Int, winName="")
    {
        winObj := This.GetWin(winName)
        winObj.MaxCount := int
    }

    ; GetMaxCount(winName) {{{2
    GetMaxCount(winName="")
    {
        winObj := This.GetWin(winName)
        return winObj.MaxCount
    }

    ; SetCount(int, winName) {{{2
    SetCount(int, winName="")
    {
        winObj := This.GetWin(winName)
        winObj.Count := int
    }

    ; GetCount(winName) {{{2
    GetCount(winName="")
    {
        winObj := This.GetWin(winName)
        return winObj.Count
    }

    ; SetTimeOut(Int, winName) {{{2
    SetTimeOut(Int, winName="")
    {
        winObj := This.GetWin(winName)
        winObj.TimeOut := int
    }

    ; GetTimeOut(winName) {{{2
    GetTimeOut(winName="")
    {
        winObj := This.GetWin(winName)
        return winObj.TimeOut
    }

    ; Map(keyName, Action, winName) {{{2
    ; 例 Map("<C-A>jjj", <a>, "TC")
    ; Map("<nowait>jk", <b>, "TC")
    Map(keyName, Action, winName="")
    {
        If not this.GetAction(Action)
        {
            If Islabel(action)
                this.SetAction(Action, Action)
            Else
            {
                msgbox % "map " keyname " to "  action  " error"
                this.ErrorCode := "MAP_ACTION_ERROR"
                return
            }
        }

        winObj := This.GetWin(winName)
        modeObj := this.GetMode(winName)
        Class:=winObj.class
        filepath := winObj.filepath
        If winName
        {
            If strlen(filepath)
                Hotkey, IfWinActive, ahk_exe %filepath%
            Else
                Hotkey, IfWinActive, ahk_class %class%
        }
        Else
            Hotkey, IfWinActive
        keyName := RegExReplace(keyName, "i)<nowait>", "", nowait)
        keyName := RegExReplace(keyName, "i)<super>", "", super)
        newkeyName := keyName
        index := 0
        Loop
        {
            If not strlen(newkeyName)
                break
            Else
            {
                saveMoreKey .= thisKey
                modeobj.SetMoreKey(saveMoreKey)
            }

            If RegExMatch(newkeyName, "P)^<.+?>", m)
            {
                thisKey := SubStr(newkeyName, 1, m)
                newkeyName := SubStr(newkeyName, m+1)
            }
            Else
            {
                thisKey := SubStr(newkeyName, 1, 1)
                newKeyName := SubStr(newkeyName, 2)
            }

            If RegExMatch(thisKey, "^([A-Z])$", m)
                thisKey := "<S-" m ">"
            SaveKeyName .= thisKey
            key := this.Convert2AHK(thisKey)
            this.Debug.Add("Map: " thiskey " to: " Action)

            If (Action <> "<Default>")
            {
                Hotkey, %Key%, Vim_Key, On, UseErrorLevel
            }
            Else
            {
                Hotkey, %Key%, Off, UseErrorLevel
            }

            If ErrorLevel
            {
                Msgbox % KeyName "`n" key "`n映射错误"
                this.ErrorCode := "MAP_KEY_ERROR"
                return
            }
            Else
            {
                winObj.SuperKeyList[key] := super
                winObj.KeyList[key] := True
                Index++
            }
        }

        modeObj.SetKeyMap(SavekeyName, Action)
        modeObj.SetNoWait(SavekeyName, nowait)
        return False
    }

    ; ExcludeWin(winName="", Bold=True) {{{2
    ExcludeWin(winName="", Bold=True)
    {
        this.ExcludeWinList[winName] := Bold
    }

    ; Toggle(winName) {{{2
    Toggle(winName)
    {
        winObj := this.GetWin(winName)
        winObj.Status := !winObj.Status
        this.Control(winObj.Status, winName)
        return winObj.Status
    }

    ; Control(bold, winName) {{{2
    Control(bold, winName="", all=false)
    {
        winObj := this.GetWin(winName)
        class := winObj.Class
        filepath := winObj.filepath
        If Strlen(filepath)
            Hotkey, IfWinActive, ahk_exe %filepath%
        Else If Strlen(class)
            Hotkey, IfWinActive, ahk_class %class%
        Else
            Hotkey, IfWinActive

        this.Debug.Add("===== Control End  =====")
        for i , k in winObj.KeyList
        {
            If winObj.SuperKeyList[i] And ( not all )
                Continue
            this.Debug.Add("class: " class "`tkey: " i "`tcontrol: " bold )
            If bold
                Hotkey, %i%, Vim_Key, On
            Else
                Hotkey, %i%, Vim_Key, off
            winObj.KeyList[i] := bold
        }
        this.Debug.Add("===== Control Start =====")
    }

    ; Copy(winName1, winName2) {{{2
    ; 复制winName1到winName2, winName2按class/filepath/title定义
    Copy(winName1, winName2, class, filepath="", title="")
    {
        this.debug.Add("Copy>> "winName1 "`t"  winName2 "`t" class)
        w1 := This.GetWin(winName1)
        w2 := this.SetWin(winName2, class, filepath, title)
        w2.class := class
        w2.filepath := filepath
        w2.title := title
        w2.KeyList := w1.KeyList
        w2.SuperKeyList := w1.SuperKeyList
        w2.modeList  := w1.modeList
        w2.mode      := w1.mode
        w2.LastKey   := w1.LastKey
        w2.KeyTemp   := w1.KeyTemp
        w2.MaxCount  := w1.MaxCount
        w2.Count     := w1.Count
        w2.TimeOut   := w1.TimeOut
        w2.Info      := w1.Info
        w2.BeforeActionDoFunc := w1.BeforeActionDoFunc
        w2.AfterActionDoFunc  := w1.AfterActionDoFunc
        w2.ShowInfoFunc := w1.ShowInfoFunc
        w2.HideInfoFunc := w1.HideInfoFunc
        this.Control(Bold:=True, winName2, all:=true)
        return w2
    }

    ; CopyMode(win, mode, to) {{{2
    ; 在当前的Win中复制一个模式
    CopyMode(winName, fromMode, toMode)
    {
        winObj := This.GetWin(winName)
        winObj.mode := modeName
        winObj.KeyTemp := ""
        winObj.Count := 0
        from := winObj.modeList[fromMode]
        from.name  := toMode
        winObj.modeList[toMode] := from
        return from
    }

    ; Delete(winName) {{{2
    Delete(winName="") {
        this.Control(False, winName, all:=True)
        this.WinList[winName] := ""
    }

    ; GetMore() {{{2
    GetMore(obj = false)
    {
        rt_obj := []
        winObj  := this.GetWin(this.LastFoundWin)
        modeObj := this.GetMode(this.LastFoundWin)
        If Strlen(winObj.KeyTemp)
        {
            r := winObj.KeyTemp "`n"
            rt_obj[1] := {"key":winObj.KeyTemp, "Action":modeObj.GetKeyMap(winObj.KeyTemp)}
            m := "i)^" this.ToMatch(winObj.KeyTemp) ".+"
            for i , k in modeObj.keymapList
            {
                If RegExMatch(i, m)
                {
                    r .= i "`t" modeObj.GetKeyMap(i) "`n"
                    rt_obj[rt_obj.MaxIndex()+1] := {"key":i, "Action":modeObj.GetKeyMap(i)}
                }
            }

            if obj
                return rt_obj
            else
                return r
        }
        Else
            If winobj.count
                return winobj.count
    }

    ; Clear() {{{2
    Clear(winName="") {
        winObj := This.GetWin(winName)
        winObj.KeyTemp := ""
        winObj.Count := 0
    }

    ; Key() {{{2
    Key()
    {
        Global __vimLastAction
        ; 获取winName
        winName := this.CheckWin()
        ; 获取当前的热键
        k := this.CheckCapsLock(this.Convert2VIM(A_ThisHotkey))
        ; 如果winName在排除窗口中，直接发送热键
        If this.ExcludeWinList[winName] {
            Send, % this.Convert2AHK(k, ToSend:=True)
            return
        }
        ; 如果当前热键在当前winName无效，判断全局热键中是否有效？
        winObj := this.GetWin(winName)
        If Not winObj.KeyList[A_thisHotkey]
        {
            winObj := this.GetWin()
            If Not winObj.KeyList[A_thisHotkey]
            {
                ; 无效热键，按普通键输出
                Send, % this.Convert2AHK(k, ToSend:=True)
                return
            }
            Else
                winName := ""
        }

        this.LastFoundWin := winName
        ; 执行在判断热键前的函数, 如果函数返回True，按普通键输出
        If IsFunc(f:=winObj.BeforeActionDoFunc){
            If %f%(){
                Send, % this.Convert2AHK(k, ToSend:=True)
                return
            }
        }

        ; 获取当前模式对应的对象
        modeObj := this.GetMode(winName)
        ; 把当前热键添加到热键缓存中, 并设置最后热键为k
        winObj.KeyTemp .= winObj.LastKey := k
        this.Debug.Add(" win: " winname "`tHotkey: " k)

        /*
            If winObj.Count
                this.Debug.Add(" [" winName "`t热键:" winObj.Count winObj.KeyTemp  )
            Else
                this.Debug.Add(" [" winName "]`t热键:" winObj.KeyTemp  )
        */

        ; 热键缓存是否有对应的Action?
        ; 判断是否有更多热键, 如果当前具有<nowait>设置，则无视更多热键
        If modeObj.GetMoreKey(winObj.KeyTemp) And (Not modeObj.GetNoWait(winObj.KeyTemp))
        {
            ; 启用TimeOut
            If strlen(modeObj.GetKeymap(winObj.KeyTemp))
                If tick := winObj.TimeOut
                    Settimer, Vim_TimeOut, %tick%

            winObj.ShowMore()
            ; 执行在判断热键后的函数, 如果函数返回True，按普通键输出
            If IsFunc(f:=winObj.AfterActionDoFunc){
                If %f%()
                    Send, % this.Convert2AHK(k, ToSend:=True)
            }

            return
        }

        ; 如果没有更多，热键缓存是否有对应的Action?
        If strlen(actionName := modeObj.GetKeymap(winObj.KeyTemp))
        {
            actObj := this.GetAction(actionName)
            If ( actObj.Type = 0 ) And RegExMatch(actionName , "^<(\d)>$", m)
            {
                ; 数字则进行累加
                winObj.Count := winObj.Count * 10 + m1
                If winObj.MaxCount And winObj.Count > winObj.MaxCount
                    winObj.Count := winObj.MaxCount

                winObj.KeyTemp := ""
                winObj.ShowMore()
                If IsFunc(f:=winObj.AfterActionDoFunc)
                    %f%()
                return
            }
            Else
            {
                ; 非数字则直接运行
                ;this.Debug.Add("act: " actionName "`tLK: " winObj.KeyTemp)
                __vimLastAction := {"LastKey":k, "winName":winName, "ActionName":ActionName, "KeyTemp":winObj.KeyTemp, "Count":winObj.Count}
                Settimer, Vim_TimeOut, Off
                actObj.Do(winObj.Count)
                winObj.Count := 0
            }
        }
        Else
        {
            Settimer, Vim_TimeOut, Off
            ; 如果没有，按普通键输出
            If strlen(actionName := modeObj.GetKeymap(winObj.LastKey))
            {
                actObj := this.GetAction(actionName)
                __vimLastAction := {"LastKey":k, "winName":winName, "ActionName":ActionName, "KeyTemp":winObj.KeyTemp, "Count":winObj.Count}
                actObj.Do(winObj.Count)
                winObj.Count := 0
            }
            Else
            {
                Send, % this.Convert2AHK(k, ToSend:=True)
                winObj.Count := 0
            }
        }

        winObj.KeyTemp := ""
        winObj.HideMore()
        ; 执行在判断热键后的函数, 如果函数返回True，按普通键输出
        If IsFunc(f:=winObj.AfterActionDoFunc)
        {
            If %f%()
                Send, % this.Convert2AHK(k, ToSend:=True)
            ; %f%() ;直接运行
        }
        return
    }

    ; IsTimeOut() {{{2
    IsTimeOut()
    {
        winObj  := this.GetWin(this.LastFoundWin)
        modeObj := this.GetMode(this.LastFoundWin)
        act := this.GetAction(modeObj.GetKeyMap(winObj.KeyTemp))
        If act
        {
            winObj.HideMore()
            __vimLastAction := {"LastKey":k, "winName":winName, "ActionName":ActionName, "KeyTemp":winObj.KeyTemp, "Count":winObj.Count}
            act.Do(winObj.Count)
            winObj.Count := 0
            winObj.KeyTemp := ""
            ; 执行在判断热键后的函数, 如果函数返回True，按普通键输出
            If IsFunc(f:=winObj.AfterActionDoFunc)
            {
                If %f%()
                Send, % this.Convert2AHK(k, ToSend:=True)
            }
            Settimer, Vim_TimeOut, Off
        }
    }

    ; Debug(Bold) {{{2
    Debug(Bold, history=false)
    {
        If Bold
        {
            this.Debug := new __vimDebug(history)
            this.Debug.var(this)
        }
        Else
        {
            GUI, vimDebug:Destroy
            this.Debug := ""
        }
    }
; TODO Code style
        ; Convert2VIM(key) {{{2
        ; 将AHK热键名转换为类VIM的热键名
        ; 例 Convert2VIM("f1")
        Convert2VIM(key)
        {
            If RegExMatch(key, "^[A-Z]$")
                return "<S-" this.Upper(key) ">"
            If RegExMatch(key, "i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$")
                return "<" key ">"
            If RegExMatch(key, "i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn))$")
                return "<" key ">"
            If RegExMatch(key, "i)^((BS)|(BackSpace))$")
                return "<BS>"
            If RegExMatch(key, "i)^((Esc)|(Escape))$")
                return "<Esc>"
            If RegExMatch(key, "i)^((Ins)|(Insert))$")
                return "<Insert>"
            If RegExMatch(key, "i)^((Del)|(Delete))$")
                return "<Delete>"
            If RegExMatch(key, "i)^PrintScreen$")
                return "<PrtSc>"
            If RegExMatch(key, "<")
                return "<LT>"
            If RegExMatch(key, ">")
                return "<LT>"
            If RegExMatch(key, "i)^shift\s&\s(.*)", m) or RegExMatch(key, "^\+(.*)", m)
                return "<S-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^lshift\s&\s(.*)", m)
                return "<LS-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^rshift\s&\s(.*)", m)
                return "<RS-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^Ctrl\s&\s(.*)", m) or RegExMatch(key, "^\^(.*)", m)
                return "<C-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^lctrl\s&\s(.*)", m)
                return "<LC-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^rctrl\s&\s(.*)", m)
                return "<RC-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^alt\s&\s(.*)", m) or RegExMatch(key, "^\!(.*)", m)
                return "<A-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^lalt\s&\s(.*)", m)
                return "<LA-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^ralt\s&\s(.*)", m)
                return "<RA-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^lwin\s&\s(.*)", m) or RegExMatch(key, "^#(.*)", m)
                return "<W-" this.Upper(m1) ">"
            If RegExMatch(key, "i)^alt$")
                return "<Alt>"
            If RegExMatch(key, "i)^ctrl$")
                return "<Ctrl>"
            If RegExMatch(key, "i)^shift$")
                return "<Shift>"
            If RegExMatch(key, "i)^lwin$")
                return "<Win>"
            return key
        }
        Upper(k)
        {
            StringUpper, k, k
            return k
        }
        ; Convert2AHK(key, ToSend=False) {{{2
        ; 将类VIM的热键名转换为AHK热键名
        ; 例 Convert2AHK("<F1>")
        Convert2AHK(key, ToSend=False)
        {
          this.CheckCapsLock(key)
            If RegExMatch(key, "^<.*>$")
            {
                key := SubStr(key, 2, strlen(key)-2)
                If RegExMatch(key, "i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$")
                    return ToSend ? "{" key "}" : key
                If RegExMatch(key, "i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn)|(BS)|(ESC)|(Insert)|(Delete))$")
                    return ToSend ? "{" key "}" : key
                If RegExMatch(key, "i)^PrtSc$")
                    return ToSend ? "{PrintScreen}" : "PrintScreen"
                If RegExMatch(key, "i)^alt$")
                    return ToSend ? "{!}" : "alt"
                If RegExMatch(key, "i)^ctrl$")
                    return ToSend ? "{^}" : "ctrl"
                If RegExMatch(key, "i)^shift$")
                    return ToSend ? "{+}" : "shift"
                If RegExMatch(key, "i)^win$")
                    return ToSend ? "{#}" : "lwin"
                If RegExMatch(key, "<LT>")
                    return "<"
                If RegExMatch(key, "<RT>")
                    return ">"
                If RegExMatch(key, "i)^S\-(.*)", m)
                    return ToSend ? "+" this.CheckToSend(m1) : "shift & " m1
                If RegExMatch(key, "i)^LS\-(.*)", m)
                    return ToSend ? "+" this.CheckToSend(m1) : "lshift & " m1
                If RegExMatch(key, "i)^RS-(.*)", m)
                    return ToSend ? "+" this.CheckToSend(m1) : "rshift & " m1
                If RegExMatch(key, "i)^C\-(.*)", m)
                    return ToSend ? "^" this.CheckToSend(m1) : "ctrl & " m1
                If RegExMatch(key, "i)^LC\-(.*)", m)
                    return ToSend ? "^" this.CheckToSend(m1) : "lctrl & " m1
                If RegExMatch(key, "i)^RC\-(.*)", m)
                    return ToSend ? "^" this.CheckToSend(m1) : "rctrl & " m1
                If RegExMatch(key, "i)^A\-(.*)", m)
                    return ToSend ? "!" this.CheckToSend(m1) : "alt & " m1
                If RegExMatch(key, "i)^LA\-(.*)", m)
                    return ToSend ? "!" this.CheckToSend(m1) : "lalt & " m1
                If RegExMatch(key, "i)^RA\-(.*)", m)
                    return ToSend ? "!" this.CheckToSend(m1) : "ralt & " m1
                If RegExMatch(key, "i)^w\-(.*)", m)
                    return ToSend ? "#" this.CheckToSend(m1) : "lwin & " m1
            }
            Else
                    return key
        }
        CheckToSend(key)
        {
            If RegExMatch(key, "i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$")
                return "{" key "}"
            If RegExMatch(key, "i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn)|(BS)|(ESC)|(Insert)|(Delete))$")
                return "{" key "}"
            If RegExMatch(key, "i)^PrtSc$")
                return "{PrintScreen}"
            If RegExMatch(key, "i)^alt$")
                return "{!}"
            If RegExMatch(key, "i)^ctrl$")
                return "{^}"
            If RegExMatch(key, "i)^shift$")
                return "{+}"
            If RegExMatch(key, "i)^win$")
                return "{#}"
            If RegExMatch(key, "<LT>")
                return "<"
            If RegExMatch(key, "<RT>")
                return ">"
      Return Key
        }
        ; CheckCapsLock(key) {{{2
        ; 检测CapsLock是否按下，返回对应的值
        ; key 的值为类VIM键，如 CheckCapsLock("<S-A>")
        CheckCapsLock(key)
        {
            If GetKeyState("CapsLock", "T")
            {
                If RegExMatch(key, "^[a-z]$")
                    return "<S-" key ">"
                If RegExMatch(key, "i)^<S\-([a-zA-Z])>", m)
        {
          StringLower, key, m1
                    return key
        }
            }
            return key
        }
        ToMatch(v)
        {
            v := RegExReplace(v , "\+|\?|\.|\*|\{|\}|\(|\)|\||\^|\$|\[|\]|\\", "\$0")
           Return RegExReplace(v , "\s", "\s")
        }
}
; Class __win {{{1
Class __win
{
    __new(class="", filepath="", title=""){
        this.class     := class
        this.filepath  := filepath
        this.title     := title
        this.KeyList   := []
        this.SuperKeyList   := []
        this.modeList  := []
        this.Status    := True
        this.mode      := ""
        this.LastKey   := ""
        this.KeyTemp   := ""
        this.MaxCount  := 99
        this.Count     := 0
        this.TimeOut   := 0
        this.Info := default_enable_show_info
        this.BeforeActionDoFunc := ""
        this.AfterActionDoFunc   := ""
        this.ShowInfoFunc := "ShowInfo"
        this.HideInfoFunc := "HideInfo"
    }
    ; ChangeMode(modeName) {{{2
    ; 检查模式是否存在，如存在则返回模式对象，如果不存在则新建并返回模式对象
    ChangeMode(modeName)
    {
        this.mode := modeName
        this.KeyTemp := ""
        this.Count := 0
        If not this.modeList[modeName]
            this.modeList[modeName] := new __Mode(modeName)
    modeObj := this.modeList[modeName]
    If IsFunc(func := modeObj.modeFunction)
      %func%()
        return modeObj
    }
  ; ExistMode() {{{2
    ; 获取当前模式名
    ExistMode()
    {
        return this.mode
    }
    ; SetInfo() {{{2
    SetInfo(bold)
    {
        this.info := bold
    }
    ; SetShowInfo() {{{2
    SetShowInfo(func)
    {
        this.ShowInfoFunc := func
    }
    ; SetHideInfo() {{{2
    SetHideInfo(func)
    {
        this.HideInfoFunc := func
    }
    ; ShowMore() {{{2
    ShowMore()
    {
        If IsFunc(f:=this.ShowInfoFunc) And this.Info
            %f%()
    }
    ; HideMore() {{{2
    HideMore()
    {
        If IsFunc(f:=this.HideInfoFunc) And this.Info
            %f%()
    }
}

; Class __Mode {{{1
Class __Mode
{
    __new(modeName)
    {
        this.name  := modeName
        this.keymapList := []
        this.keymoreList := []
        this.nowaitList := []
        this.modeFunction := ""
    }
    ; SetKeyMap(key, action) {{{2
    SetKeyMap(key, action)
    {
        this.keymapList[key] := action
    }
    ; GetKeyMap(key) {{{2
    GetKeyMap(key)
    {
        return this.keymapList[key]
    }
    ; DelKeyMap(key) {{{2
    DelKeyMap(key)
    {
        this.keymapList[key] := ""
    }
    ; SetNoWait(key, bold) {{{2
    ; 无视TimeOut执行热键
    SetNoWait(key, bold)
    {
        this.nowaitList[key] := bold
    }
    ; GetNoWait(key) {{{2
    GetNoWait(key)
    {
        return this.nowaitList[key]
    }
    ; SetMoreKey(key) {{{2
    SetMoreKey(key)
    {
        this.keymoreList[key] := true
    }
    ; GetMoreKey(key) {{{2
    GetMoreKey(key)
    {
        return this.keymoreList[key]
    }
}
; Class __Action {{{1
Class __Action
{
        ; Action 有几种类型
        ; 0 代表执行Action对应的Label (默认)
        ; 1 代表执行Function的值对应的函数
        ; 2 代表运行CmdLine对应的值
        ; 3 代表发送HotString对应的文本

    __new(Name, Comment){
        this.Name := Name
        this.Comment := Comment
        this.MaxTimes := 0
        this.Type := 0
    this.Function := ""
    this.CmdLine := ""
    this.HotString := ""
    }
    ; SetFunction(Function) {{{2
    ; 设置Action执行的函数名
    SetFunction(Function)
    {
        this.Function := Function
        this.Type := 1
    }
    ; SetCmdLine(CmdLine) {{{2
    ; 设置Action运行的字符串
    SetCmdLine(CmdLine)
    {
        this.CmdLine := CmdLine
        this.Type := 2
    }
    ; SetHotString(HotString) {{{2
    ; 设置Action发送的文本
    SetHotString(HotString)
    {
        this.HotString := HotString
        this.Type := 3
    }
    ; SetMaxTimes(Times) {{{2
    ; 设置最大运行次数
    SetMaxTimes(Times)
    {
        this.MaxTimes := Times
    }
    ; Do(Times=1) {{{2
    ; 执行Action
    Do(Times=0)
    {
        Times := !Times ? 1 : Times
        If this.MaxTimes And ( Times > this.MaxTimes)
                Times := this.MaxTimes
        Loop, %Times%
        {
            If this.Type = 0
            {
                If IsLabel(l:=this.Name)
                    GoSub, %l%
            }
            If this.Type = 1
            {
                If IsFunc(f:=this.Function)
                    %f%()
            }
            If this.Type = 2
            {
                c := this.CmdLine
                Run, %cmd%
            }
            If This.Type = 3
            {
                t := this.HotString
                Send, %t%
            }
        }
    }
}

; Class __Plugin {{{1
Class __Plugin
{
    __new(PluginName)
    {
            this.PluginName := PluginName
            this.Author := ""
            this.Ver := ""
            this.Comment := ""
    }
    ; CheckSub() {{{2
    CheckSub()
    {
            If IsLabel(p:=this.PluginName)
            {
                GoSub, %p%
                this.Error := False
            }
            Else
                this.Error := True
    }
}
; Class __vimDebug {{{1
Class __vimDebug
{
    __new(key)
    {
    this.mode := key
    If key
    {
        GUI, vimDebug:Destroy
        GUI, vimDebug:+hwnd_vimdebug  -Caption +ToolWindow +Border
        GUI, vimDebug:color, 454545, 454545
        GUI, vimDebug:font, s16 cFFFFFF
        GUI, vimDebug:Add, Edit, x-2 y-2 w400 h60 readonly
        GUI, vimDebug:Show, w378 h56 y600
    WinSet, AlwaysOnTop, On, ahk_id %_vimdebug%
    }
    Else
    {
          GUI, vimDebug:font, s12
          GUI, vimDebug:Destroy
          GUI, vimDebug:Add, Edit, x10 y10 w400 h300 readonly
          GUI, vimDebug:Add, Edit, x10 y320 w400 h26 readonly
          GUI, vimDebug:Show, w420 h356
    }
    }
  var(obj)
  {
    this.vim := obj
  }
    Set(v)
    {
    winName := this.vim.CheckWin()
    winObj := this.vim.GetWin(winName)
    If winObj.Count
             k := " 热键缓存:" winObj.Count winObj.KeyTemp
    Else
             k := " 热键缓存:" winObj.KeyTemp
        GUI, vimDebug:Default
        GUIControl, , Edit1, %v%
        GUIControl, , Edit2, %k%
    }
    Get()
    {
        GUI, vimDebug:Default
        GUIControlGet, v, , Edit1
        return v
    }
    ; Add(v) {{{2
    Add(v)
    {
        b:=this.Get()
    If this.mode
          this.Set(b)
    else
          this.Set(v "`n" b)
    }
    ; Clear() {{{2
    Clear()
    {
        this.Set("")
    }
}

; 初始化class_Vim
vim_Init:
	#UseHook
	SetKeyDelay,-1
return
; 用于热键映射
vim_Key:
	vim.Key()
return
; 用于热键超时
vim_TimeOut:
	vim.IsTimeOut()
return
; 用于Count计数
Internal:
	__v.SetPlugin("Internal","Array","0.1","内置插件")
	__v.SetAction("<1>","Number 1")
	__v.SetAction("<2>","Number 2")
	__v.SetAction("<3>","Number 3")
	__v.SetAction("<4>","Number 4")
	__v.SetAction("<5>","Number 5")
	__v.SetAction("<6>","Number 6")
	__v.SetAction("<7>","Number 7")
	__v.SetAction("<8>","Number 8")
	__v.SetAction("<9>","Number 9")
	__v.SetAction("<0>","Number 0")
	__v.SetAction("<>","Null")
	__v.SetAction("<Default>","恢复默认")
	__v.SetAction("<Pass>","空操作")
	__v := ""
return
<1>:
<2>:
<3>:
<4>:
<5>:
<6>:
<7>:
<8>:
<9>:
<0>:
<>:
<Default>:
<Pass>:
return

Class_vim()
{
	global __v
	GoSub,Vim_Init
	__v := v :=new __vim
	__v.LoadPlugin("Internal")
	return v
}

GetLastAction()
{
  global __vimLastAction
  return __vimLastAction
}

ShowInfo()
{
	Global vim
  obj := vim.GetMore(true)
	winObj  := vim.GetWin(vim.LastFoundWin)
  if winObj.Count
      np .= winObj.Count
  Loop, % obj.MaxIndex()
  {
     act := vim.GetAction(obj[A_Index]["Action"])
     np .= obj[A_Index]["key"] "`t" act.Comment "`n"
     If (A_Index = 1)
        np .= "=====================`n"
  }
  MouseGetPos, posx, posy, A
  posx += 60
  posy += 60
	Tooltip, %np%, %posx%, %posy%
}
HideInfo()
{
	Tooltip
}

; 定义数据结构
; Class __vim {{{1
Class __vim
{
		__new()
		{
				this.PluginList := []
				this.WinList    := []
				this.WinInfo    := []
				this.ActionList := []
				this.ActionFromPlugin := []
				this.ExcludeWinList :=[]
				this.winGlobal  := new __win
				this.ErrorCode  := 0
				tihs.ActionFromPluginName := ""
				this.LastFoundWin := ""
		}

		; LoadPlugin(PluginName) {{{2
		; 用于注册插件
		LoadPlugin(PluginName)
		{
			If this.PluginList[PluginName]
				return this.PluginList[PluginName]
			p := new __Plugin(PluginName)
			this.PluginList[PluginName] := p
			back := this.ActionFromPluginName
			this.ActionFromPluginName := PluginName
			p.CheckSub()
			If p.Error
			{
				msgbox load plugin "%PluginName%" error
				this.ActionFromPluginName := back
			}
		}
		; SetPlugin(PluginName,Author="",Ver="",Comment="") {{{2
		; 设置Plugin信息
		SetPlugin(PluginName,Author="",Ver="",Comment="")
		{
			p := this.PluginList[PluginName]
			p.Author := Author
			p.Ver := Ver
			p.Comment := Comment
		}
		; GetPlugin(PluginName) {{{2
		; 获取Plugin信息
		GetPlugin(PluginName)
		{
			return this.PluginList[PluginName]
		}
    ; Comment(action,desc,complex=1) {{{2
    ; 兼容老版本的vimcore.ahk
    Comment(action,desc="",complex=1)
    {
      act := this.SetAction(Action,Desc)
      If not complex ; 不允许多次运行
	      act.SetMaxTimes(1)
      return act
    }
		; SetAction(Name,Comment) {{{2
		; 用于为Action(动作)进行注释
		SetAction(Name,Comment="")
		{
			If this.ActionList[Name]
				ra := This.ActionList[Name]
			Else
				ra := This.ActionList[Name] := new __Action(Name,Comment)
			This.ActionFromPlugin[Name] := this.ActionFromPluginName
			return ra
		}
		; GetAction(Name) {{{2
		; 获取Action的信息
		GetAction(Name)
		{
			return this.ActionList[Name]
		}
		; SetWin(winName,class,filepath,title) {{{2
		; 添加win成员
		SetWin(winName,class,filepath="",title="")
		{
			If this.WinList[winName]
				rw := this.WinList[winName]
			Else
				rw := this.WinList[winName] := new __win(class,filepath,title)
			this.WinInfo["class`t"class]       := winName
			this.WinInfo["filepath`t"filepath] := winName
			this.WinInfo["title`t"title]       := winName
			return rw
		}
		; GetWin(winName) {{{2
		GetWin(winName="")
		{
			If strlen(winName)
				return this.WinList[winName]
			Else
				return this.winGlobal
		}
    	; CheckWin() {{{2
		CheckWin()
		{
/*
			WinGetTitle,t,A
			If Strlen(winName:=this.WinInfo["title`t"t])
				return winName
*/
			WinGet,f,ProcessName,A
			If Strlen(winName:=this.WinInfo["filepath`t"f])
				return winName
			WinGetClass,c,A
			If Strlen(winName:=this.WinInfo["class`t"c])
				return winName
		}
		; mode(mode,win="") {{{2
    ; 兼容老版本的vimcore.ahk
		mode(mode,win="")
    {
      If not IsObject(this.GetWin(win))
        this.SetWin(win,win)
      return this.SetMode(mode,win)
    }
		; SetMode(modeName,winName) {{{2
		SetMode(modeName,winName="")
		{
			winObj := This.GetWin(winName)
			return winObj.ChangeMode(modeName)
		}
    ; SetModeFunction(func,modeName,winName="") {{{2
    SetModeFunction(func,modeName,winName="")
    {
			winObj := This.GetWin(winName)
		  modeObj := winObj.modeList[modeName]
      modeObj.modeFunction := func
    }
    ; GetMode(winName) {{{2
		; 获取指定win中当前的模式
		GetMode(winName="")
		{
			winObj := This.GetWin(winName)
			return winObj.modeList[winobj.ExistMode()]
		}
    ; GetInputState {{{2
    GetInputState(WinTitle="A")
    {
        ControlGet,hwnd,HWND,,,%WinTitle%
        if (A_Cursor = "IBeam")
            return 1
        if (WinActive(WinTitle))
        {
					ptrSize := !A_PtrSize ? 4 : A_PtrSize
					VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
					NumPut(cbSize, stGTI,  0, "UInt")   ;   DWORD   cbSize;
					hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
									 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
        }
        return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283  ;Message : WM_IME_CONTROL
          ,  Int, 0x0005  ;wParam  : IMC_GETOPENSTATUS
          ,  Int, 0)      ;lParam  : 0
    }
		; BeforeActionDo(Function,winName="") {{{2
		BeforeActionDo(Function,winName="")
		{
			winObj  := this.GetWin(winName)
			winObj.BeforeActionDoFunc:= Function
		}
		; AfterActionDo(Function,winName="") {{{2
		AfterActionDo(Function,winName="")
		{
			winObj  := this.GetWin(winName)
			winObj.AfterActionDoFunc:= Function
		}

		;
		; SetMaxCount(Int,winName) {{{2
		SetMaxCount(Int,winName="")
		{
			winObj := This.GetWin(winName)
			winObj.MaxCount := int
		}
		; GetMaxCount(winName) {{{2
		GetMaxCount(winName="")
		{
			winObj := This.GetWin(winName)
			return winObj.MaxCount
		}
		; SetCount(int,winName) {{{2
		SetCount(int,winName="")
		{
			winObj := This.GetWin(winName)
			winObj.Count := int
		}
		; GetCount(winName) {{{2
		GetCount(winName="")
		{
			winObj := This.GetWin(winName)
			return winObj.Count
		}
		; SetTimeOut(Int,winName) {{{2
		SetTimeOut(Int,winName="")
		{
			winObj := This.GetWin(winName)
			winObj.TimeOut := int
		}
		; GetTimeOut(winName) {{{2
		GetTimeOut(winName="")
		{
			winObj := This.GetWin(winName)
			return winObj.TimeOut
		}

		; Map(keyName,Action,winName) {{{2
		; 例 Map("<C-A>jjj",<a>,"TC")
		; Map("<nowait>jk",<b>,"TC")
		Map(keyName,Action,winName="")
		{
			If not this.GetAction(Action)
			{
          If Islabel(action)
            this.SetAction(Action,Action)
          Else
          {
					  msgbox % "map " keyname " to "  action  " error"
            this.ErrorCode := "MAP_ACTION_ERROR"
					  return
          }
			}
			winObj := This.GetWin(winName)
			modeObj := this.GetMode(winName)
			Class:=winObj.class
      filepath := winObj.filepath
			If winName
      {
        If strlen(filepath)
          Hotkey,IfWinActive,ahk_exe %filepath%
        Else
				  Hotkey,IfWinActive,ahk_class %class%
      }
			Else
				Hotkey,IfWinActive
			keyName := RegExReplace(keyName,"i)<nowait>","",nowait)
			keyName := RegExReplace(keyName,"i)<super>","",super)
			newkeyName := keyName
			index := 0
			Loop
			{
				If not strlen(newkeyName)
					break
				Else
				{
					saveMoreKey .= thisKey
					modeobj.SetMoreKey(saveMoreKey)
				}
				If RegExMatch(newkeyName,"P)^<.+?>",m)
				{
					thisKey := SubStr(newkeyName,1,m)
					newkeyName := SubStr(newkeyName,m+1)
				}
				Else
				{
					thisKey := SubStr(newkeyName,1,1)
					newKeyName := SubStr(newkeyName,2)
				}
				If RegExMatch(thisKey,"^([A-Z])$",m)
					thisKey := "<S-" m ">"
				SaveKeyName .= thisKey
				key := this.Convert2AHK(thisKey)
				this.Debug.Add("Map: " thiskey " to: " Action)
                If (Action <> "<Default>")
                {
                    Hotkey,%Key%,Vim_Key,On,UseErrorLevel
                }
                Else
                {
                    Hotkey, %Key%, Off, UseErrorLevel
                }
				If ErrorLevel
        {
					Msgbox % KeyName "`n" key "`n映射错误"
          this.ErrorCode := "MAP_KEY_ERROR"
          return
        }
				Else
				{
					winObj.SuperKeyList[key] := super
					winObj.KeyList[key] := True
					Index++
				}
			}
			modeObj.SetKeyMap(SavekeyName,Action)
			modeObj.SetNoWait(SavekeyName,nowait)
      return False
		}

		; ExcludeWin(winName="",Bold=True) {{{2
		ExcludeWin(winName="",Bold=True)
		{
			this.ExcludeWinList[winName] := Bold
		}
		; Toggle(winName) {{{2
		Toggle(winName)
		{
			winObj := this.GetWin(winName)
			winObj.Status := !winObj.Status
			this.Control(winObj.Status,winName)
      return winObj.Status
		}
 		; Control(bold,winName) {{{2
 		Control(bold,winName="",all=false)
		{
			winObj := this.GetWin(winName)
			class := winObj.Class
      filepath := winObj.filepath
      If Strlen(filepath)
        Hotkey,IfWinActive,ahk_exe %filepath%
			Else If Strlen(class)
				Hotkey,IfWinActive,ahk_class %class%
			Else
				Hotkey,IfWinActive
			this.Debug.Add("===== Control End  =====")
			for i , k in winObj.KeyList
			{
				If winObj.SuperKeyList[i] And ( not all )
					Continue
				this.Debug.Add("class: " class "`tkey: " i "`tcontrol: " bold )
				If bold
					Hotkey,%i%,Vim_Key,On
				Else
					Hotkey,%i%,Vim_Key,off
                ;if k = "<Default>":
                ;    msgbox % k
				winObj.KeyList[i] := bold
			}
			this.Debug.Add("===== Control Start =====")
		}
		; Copy(winName1,winName2) {{{2
    ; 复制winName1到winName2,winName2按class/filepath/title定义
		Copy(winName1,winName2,class,filepath="",title="")
		{
			this.debug.Add("Copy>> "winName1 "`t"  winName2 "`t" class)
			w1 := This.GetWin(winName1)
			w2 := this.SetWin(winName2,class,filepath,title)
			w2.class := class
			w2.filepath := filepath
			w2.title := title
			w2.KeyList := w1.KeyList
			w2.SuperKeyList := w1.SuperKeyList
			w2.modeList  := w1.modeList
			w2.mode      := w1.mode
			w2.LastKey   := w1.LastKey
			w2.KeyTemp   := w1.KeyTemp
			w2.MaxCount  := w1.MaxCount
			w2.Count     := w1.Count
			w2.TimeOut   := w1.TimeOut
			w2.Info      := w1.Info
			w2.BeforeActionDoFunc := w1.BeforeActionDoFunc
			w2.AfterActionDoFunc  := w1.AfterActionDoFunc
			w2.ShowInfoFunc := w1.ShowInfoFunc
			w2.HideInfoFunc := w1.HideInfoFunc
			this.Control(Bold:=True,winName2,all:=true)
      return w2
		}

    ; CopyMode(win,mode,to) {{{2
    ; 在当前的Win中复制一个模式
    CopyMode(winName,fromMode,toMode)
    {
			winObj := This.GetWin(winName)
		  winObj.mode := modeName
		  winObj.KeyTemp := ""
		  winObj.Count := 0
			from:=winObj.modeList[fromMode]
      from.name  := toMode
      winObj.modeList[toMode] := from
      return from
    }

		; Delete(winName) {{{2
		Delete(winName="") {
			this.Control(False,winName,all:=True)
			this.WinList[winName] := ""
		}

		; GetMore() {{{2
		GetMore(obj=false)
		{
      rt_obj := []
			winObj  := this.GetWin(this.LastFoundWin)
			modeObj := this.GetMode(this.LastFoundWin)
      If Strlen(winObj.KeyTemp)
      {
			  r := winObj.KeyTemp "`n"
        rt_obj[1] := {"key":winObj.KeyTemp,"Action":modeObj.GetKeyMap(winObj.KeyTemp)}
			  m := "i)^" this.ToMatch(winObj.KeyTemp) ".+"
			  for i ,k in modeObj.keymapList
			  {
				  If RegExMatch(i,m)
          {
					  r .= i "`t" modeObj.GetKeyMap(i) "`n"
            rt_obj[rt_obj.MaxIndex()+1] := {"key":i,"Action":modeObj.GetKeyMap(i)}
          }
			  }
        if obj
            return rt_obj
        else
			      return r
      }
      Else
        If winobj.count
          return winobj.count
		}
		; Clear() {{{2
		Clear(winName="") {
			winObj := This.GetWin(winName)
			winObj.KeyTemp := ""
			winObj.Count := 0
		}

		; Key() {{{2
		Key()
		{
      Global __vimLastAction
			; 获取winName
			winName := this.CheckWin()
			; 获取当前的热键
			k := this.CheckCapsLock(this.Convert2VIM(A_ThisHotkey))
			; 如果winName在排除窗口中，直接发送热键
			If this.ExcludeWinList[winName] {
					Send,% this.Convert2AHK(k,ToSend:=True)
					return
			}
			; 如果当前热键在当前winName无效，判断全局热键中是否有效？
			winObj := this.GetWin(winName)
			If Not winObj.KeyList[A_thisHotkey] {
				winObj := this.GetWin()
				If Not winObj.KeyList[A_thisHotkey] {
					; 无效热键，按普通键输出
					Send,% this.Convert2AHK(k,ToSend:=True)
					return
				}
				Else
					winName := ""
			}
			this.LastFoundWin := winName
			; 执行在判断热键前的函数,如果函数返回True，按普通键输出
			If IsFunc(f:=winObj.BeforeActionDoFunc){
				If %f%(){
					Send,% this.Convert2AHK(k,ToSend:=True)
					return
				}
			}
			; 获取当前模式对应的对象
			modeObj := this.GetMode(winName)
			; 把当前热键添加到热键缓存中,并设置最后热键为k
			winObj.KeyTemp .= winObj.LastKey := k
			this.Debug.Add(" win: " winname "`tHotkey: " k)
/*
      If winObj.Count
			  this.Debug.Add(" [" winName "`t热键:" winObj.Count winObj.KeyTemp  )
      Else
			  this.Debug.Add(" [" winName "]`t热键:" winObj.KeyTemp  )
*/
			; 热键缓存是否有对应的Action?
			; 判断是否有更多热键,如果当前具有<nowait>设置，则无视更多热键
			If modeObj.GetMoreKey(winObj.KeyTemp) And (Not modeObj.GetNoWait(winObj.KeyTemp)) {
				; 启用TimeOut
        If strlen(modeObj.GetKeymap(winObj.KeyTemp))
				    If tick := winObj.TimeOut
					      Settimer,Vim_TimeOut,%tick%
				winObj.ShowMore()
				; 执行在判断热键后的函数,如果函数返回True，按普通键输出
				If IsFunc(f:=winObj.AfterActionDoFunc){
					If %f%()
						Send,% this.Convert2AHK(k,ToSend:=True)
				}
				return
			}
			; 如果没有更多，热键缓存是否有对应的Action?
			If strlen(actionName := modeObj.GetKeymap(winObj.KeyTemp)) {
				actObj := this.GetAction(actionName)
				If ( actObj.Type = 0 ) And RegExMatch(actionName ,"^<(\d)>$",m) {
					; 数字则进行累加
					winObj.Count := winObj.Count * 10 + m1
					If winObj.MaxCount And winObj.Count > winObj.MaxCount
						winObj.Count := winObj.MaxCount
			    winObj.KeyTemp := ""
				  winObj.ShowMore()
				  If IsFunc(f:=winObj.AfterActionDoFunc)
					  %f%()
          return
				}
				Else {
					; 非数字则直接运行
			    ;this.Debug.Add("act: " actionName "`tLK: " winObj.KeyTemp)
          __vimLastAction := {"LastKey":k,"winName":winName,"ActionName":ActionName,"KeyTemp":winObj.KeyTemp,"Count":winObj.Count}
		      Settimer,Vim_TimeOut,Off
					actObj.Do(winObj.Count)
					winObj.Count := 0
				}
			}
			Else {
		    Settimer,Vim_TimeOut,Off
				; 如果没有，按普通键输出
				If strlen(actionName := modeObj.GetKeymap(winObj.LastKey))
				{
					actObj := this.GetAction(actionName)
          __vimLastAction := {"LastKey":k,"winName":winName,"ActionName":ActionName,"KeyTemp":winObj.KeyTemp,"Count":winObj.Count}
					actObj.Do(winObj.Count)
					winObj.Count := 0
				}
				Else
				{
					Send,% this.Convert2AHK(k,ToSend:=True)
					winObj.Count := 0
				}
			}
			winObj.KeyTemp := ""
			winObj.HideMore()
			; 执行在判断热键后的函数,如果函数返回True，按普通键输出
			If IsFunc(f:=winObj.AfterActionDoFunc){
				If %f%()
					Send,% this.Convert2AHK(k,ToSend:=True)
        ; %f%() ;直接运行
			}
			return
		}
		; IsTimeOut() {{{2
		IsTimeOut()
		{
			winObj  := this.GetWin(this.LastFoundWin)
			modeObj := this.GetMode(this.LastFoundWin)
			act := this.GetAction(modeObj.GetKeyMap(winObj.KeyTemp))
			If act
			{
				winObj.HideMore()
        __vimLastAction := {"LastKey":k,"winName":winName,"ActionName":ActionName,"KeyTemp":winObj.KeyTemp,"Count":winObj.Count}
				act.Do(winObj.Count)
				winObj.Count := 0
				winObj.KeyTemp := ""
				; 执行在判断热键后的函数,如果函数返回True，按普通键输出
				If IsFunc(f:=winObj.AfterActionDoFunc){
					If %f%()
						Send,% this.Convert2AHK(k,ToSend:=True)
				}
				Settimer,Vim_TimeOut,Off
			}
		}
		; Debug(Bold) {{{2
		Debug(Bold,history=false)
		{
			If Bold
      {
				this.Debug := new __vimDebug(history)
        this.Debug.var(this)
      }
			Else
      {
		    GUI,vimDebug:Destroy
				this.Debug := ""
      }
		}
		; Convert2VIM(key) {{{2
		; 将AHK热键名转换为类VIM的热键名
		; 例 Convert2VIM("f1")
		Convert2VIM(key)
		{
			If RegExMatch(key,"^[A-Z]$")
				return "<S-" this.Upper(key) ">"
			If RegExMatch(key,"i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$")
				return "<" key ">"
			If RegExMatch(key,"i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn))$")
				return "<" key ">"
			If RegExMatch(key,"i)^((BS)|(BackSpace))$")
				return "<BS>"
			If RegExMatch(key,"i)^((Esc)|(Escape))$")
				return "<Esc>"
			If RegExMatch(key,"i)^((Ins)|(Insert))$")
				return "<Insert>"
			If RegExMatch(key,"i)^((Del)|(Delete))$")
				return "<Delete>"
			If RegExMatch(key,"i)^PrintScreen$")
				return "<PrtSc>"
			If RegExMatch(key,"<")
				return "<LT>"
			If RegExMatch(key,">")
				return "<LT>"
			If RegExMatch(key,"i)^shift\s&\s(.*)",m) or RegExMatch(key,"^\+(.*)",m)
				return "<S-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^lshift\s&\s(.*)",m)
				return "<LS-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^rshift\s&\s(.*)",m)
				return "<RS-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^Ctrl\s&\s(.*)",m) or RegExMatch(key,"^\^(.*)",m)
				return "<C-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^lctrl\s&\s(.*)",m)
				return "<LC-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^rctrl\s&\s(.*)",m)
				return "<RC-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^alt\s&\s(.*)",m) or RegExMatch(key,"^\!(.*)",m)
				return "<A-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^lalt\s&\s(.*)",m)
				return "<LA-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^ralt\s&\s(.*)",m)
				return "<RA-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^lwin\s&\s(.*)",m) or RegExMatch(key,"^#(.*)",m)
				return "<W-" this.Upper(m1) ">"
			If RegExMatch(key,"i)^alt$")
				return "<Alt>"
			If RegExMatch(key,"i)^ctrl$")
				return "<Ctrl>"
			If RegExMatch(key,"i)^shift$")
				return "<Shift>"
			If RegExMatch(key,"i)^lwin$")
				return "<Win>"
			return key
		}
		Upper(k)
		{
			StringUpper,k,k
			return k
		}
		; Convert2AHK(key,ToSend=False) {{{2
		; 将类VIM的热键名转换为AHK热键名
		; 例 Convert2AHK("<F1>")
		Convert2AHK(key,ToSend=False)
		{
		  this.CheckCapsLock(key)
			If RegExMatch(key,"^<.*>$")
			{
				key := SubStr(key,2,strlen(key)-2)
				If RegExMatch(key,"i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$")
					return ToSend ? "{" key "}" : key
				If RegExMatch(key,"i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn)|(BS)|(ESC)|(Insert)|(Delete))$")
					return ToSend ? "{" key "}" : key
				If RegExMatch(key,"i)^PrtSc$")
					return ToSend ? "{PrintScreen}" : "PrintScreen"
				If RegExMatch(key,"i)^alt$")
					return ToSend ? "{!}" : "alt"
				If RegExMatch(key,"i)^ctrl$")
					return ToSend ? "{^}" : "ctrl"
				If RegExMatch(key,"i)^shift$")
					return ToSend ? "{+}" : "shift"
				If RegExMatch(key,"i)^win$")
					return ToSend ? "{#}" : "lwin"
				If RegExMatch(key,"<LT>")
					return "<"
				If RegExMatch(key,"<RT>")
					return ">"
				If RegExMatch(key,"i)^S\-(.*)",m)
					return ToSend ? "+" this.CheckToSend(m1) : "shift & " m1
				If RegExMatch(key,"i)^LS\-(.*)",m)
					return ToSend ? "+" this.CheckToSend(m1) : "lshift & " m1
				If RegExMatch(key,"i)^RS-(.*)",m)
					return ToSend ? "+" this.CheckToSend(m1) : "rshift & " m1
				If RegExMatch(key,"i)^C\-(.*)",m)
					return ToSend ? "^" this.CheckToSend(m1) : "ctrl & " m1
				If RegExMatch(key,"i)^LC\-(.*)",m)
					return ToSend ? "^" this.CheckToSend(m1) : "lctrl & " m1
				If RegExMatch(key,"i)^RC\-(.*)",m)
					return ToSend ? "^" this.CheckToSend(m1) : "rctrl & " m1
				If RegExMatch(key,"i)^A\-(.*)",m)
					return ToSend ? "!" this.CheckToSend(m1) : "alt & " m1
				If RegExMatch(key,"i)^LA\-(.*)",m)
					return ToSend ? "!" this.CheckToSend(m1) : "lalt & " m1
				If RegExMatch(key,"i)^RA\-(.*)",m)
					return ToSend ? "!" this.CheckToSend(m1) : "ralt & " m1
				If RegExMatch(key,"i)^w\-(.*)",m)
					return ToSend ? "#" this.CheckToSend(m1) : "lwin & " m1
			}
			Else
					return key
		}
		CheckToSend(key)
		{
			If RegExMatch(key,"i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$")
				return "{" key "}"
			If RegExMatch(key,"i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn)|(BS)|(ESC)|(Insert)|(Delete))$")
				return "{" key "}"
			If RegExMatch(key,"i)^PrtSc$")
				return "{PrintScreen}"
			If RegExMatch(key,"i)^alt$")
				return "{!}"
			If RegExMatch(key,"i)^ctrl$")
				return "{^}"
			If RegExMatch(key,"i)^shift$")
				return "{+}"
			If RegExMatch(key,"i)^win$")
				return "{#}"
			If RegExMatch(key,"<LT>")
				return "<"
			If RegExMatch(key,"<RT>")
				return ">"
      Return Key
		}
		; CheckCapsLock(key) {{{2
		; 检测CapsLock是否按下，返回对应的值
		; key 的值为类VIM键，如 CheckCapsLock("<S-A>")
		CheckCapsLock(key)
		{
			If GetKeyState("CapsLock","T")
			{
				If RegExMatch(key,"^[a-z]$")
					return "<S-" key ">"
				If RegExMatch(key,"i)^<S\-([a-zA-Z])>",m)
        {
          StringLower, key, m1
					return key
        }
			}
			return key
		}
		ToMatch(v)
		{
			v := RegExReplace(v ,"\+|\?|\.|\*|\{|\}|\(|\)|\||\^|\$|\[|\]|\\","\$0")
   		Return RegExReplace(v ,"\s","\s")
		}
}
; Class __win {{{1
Class __win
{
	__new(class="",filepath="",title=""){
		this.class     := class
		this.filepath  := filepath
		this.title     := title
		this.KeyList   := []
		this.SuperKeyList   := []
		this.modeList  := []
		this.Status    := True
		this.mode      := ""
		this.LastKey   := ""
		this.KeyTemp   := ""
		this.MaxCount  := 99
		this.Count     := 0
		this.TimeOut   := 0
		this.Info := default_enable_show_info
		this.BeforeActionDoFunc := ""
		this.AfterActionDoFunc   := ""
		this.ShowInfoFunc := "ShowInfo"
		this.HideInfoFunc := "HideInfo"
	}
	; ChangeMode(modeName) {{{2
	; 检查模式是否存在，如存在则返回模式对象，如果不存在则新建并返回模式对象
	ChangeMode(modeName)
	{
		this.mode := modeName
		this.KeyTemp := ""
		this.Count := 0
		If not this.modeList[modeName]
			this.modeList[modeName] := new __Mode(modeName)
    modeObj := this.modeList[modeName]
    If IsFunc(func := modeObj.modeFunction)
      %func%()
		return modeObj
	}
  ; ExistMode() {{{2
	; 获取当前模式名
	ExistMode()
	{
		return this.mode
	}
	; SetInfo() {{{2
	SetInfo(bold)
	{
		this.info := bold
	}
	; SetShowInfo() {{{2
	SetShowInfo(func)
	{
		this.ShowInfoFunc := func
	}
	; SetHideInfo() {{{2
	SetHideInfo(func)
	{
		this.HideInfoFunc := func
	}
	; ShowMore() {{{2
	ShowMore()
	{
		If IsFunc(f:=this.ShowInfoFunc) And this.Info
			%f%()
	}
	; HideMore() {{{2
	HideMore()
	{
		If IsFunc(f:=this.HideInfoFunc) And this.Info
			%f%()
	}
}

; Class __Mode {{{1
Class __Mode
{
	__new(modeName)
	{
		this.name  := modeName
		this.keymapList := []
		this.keymoreList := []
		this.nowaitList := []
		this.modeFunction := ""
	}
	; SetKeyMap(key,action) {{{2
	SetKeyMap(key,action)
	{
		this.keymapList[key] := action
	}
	; GetKeyMap(key) {{{2
	GetKeyMap(key)
	{
		return this.keymapList[key]
	}
	; DelKeyMap(key) {{{2
	DelKeyMap(key)
	{
		this.keymapList[key] := ""
	}
	; SetNoWait(key,bold) {{{2
	; 无视TimeOut执行热键
	SetNoWait(key,bold)
	{
		this.nowaitList[key] := bold
	}
	; GetNoWait(key) {{{2
	GetNoWait(key)
	{
		return this.nowaitList[key]
	}
	; SetMoreKey(key) {{{2
	SetMoreKey(key)
	{
		this.keymoreList[key] := true
	}
	; GetMoreKey(key) {{{2
	GetMoreKey(key)
	{
		return this.keymoreList[key]
	}
}
; Class __Action {{{1
Class __Action
{
		; Action 有几种类型
		; 0 代表执行Action对应的Label (默认)
		; 1 代表执行Function的值对应的函数
		; 2 代表运行CmdLine对应的值
		; 3 代表发送HotString对应的文本

	__new(Name,Comment){
		this.Name := Name
		this.Comment := Comment
		this.MaxTimes := 0
		this.Type := 0
    this.Function := ""
    this.CmdLine := ""
    this.HotString := ""
	}
	; SetFunction(Function) {{{2
	; 设置Action执行的函数名
	SetFunction(Function)
	{
		this.Function := Function
		this.Type := 1
	}
	; SetCmdLine(CmdLine) {{{2
	; 设置Action运行的字符串
	SetCmdLine(CmdLine)
	{
		this.CmdLine := CmdLine
		this.Type := 2
	}
	; SetHotString(HotString) {{{2
	; 设置Action发送的文本
	SetHotString(HotString)
	{
		this.HotString := HotString
		this.Type := 3
	}
	; SetMaxTimes(Times) {{{2
	; 设置最大运行次数
	SetMaxTimes(Times)
	{
		this.MaxTimes := Times
	}
	; Do(Times=1) {{{2
	; 执行Action
	Do(Times=0)
	{
		Times := !Times ? 1 : Times
		If this.MaxTimes And ( Times > this.MaxTimes)
				Times := this.MaxTimes
		Loop,%Times%
		{
			If this.Type = 0
			{
				If IsLabel(l:=this.Name)
					GoSub,%l%
			}
			If this.Type = 1
			{
				If IsFunc(f:=this.Function)
					%f%()
			}
			If this.Type = 2
			{
				c := this.CmdLine
				Run,%cmd%
			}
			If This.Type = 3
			{
				t := this.HotString
				Send,%t%
			}
		}
	}
}

; Class __Plugin {{{1
Class __Plugin
{
	__new(PluginName)
	{
			this.PluginName := PluginName
			this.Author := ""
			this.Ver := ""
			this.Comment := ""
	}
	; CheckSub() {{{2
	CheckSub()
	{
			If IsLabel(p:=this.PluginName)
			{
				GoSub,%p%
				this.Error := False
			}
			Else
				this.Error := True
	}
}
; Class __vimDebug {{{1
Class __vimDebug
{
	__new(key)
	{
    this.mode := key
    If key
    {
		GUI,vimDebug:Destroy
		GUI,vimDebug:+hwnd_vimdebug  -Caption +ToolWindow +Border
		GUI,vimDebug:color,454545,454545
		GUI,vimDebug:font,s16 cFFFFFF
		GUI,vimDebug:Add,Edit,x-2 y-2 w400 h60 readonly
		GUI,vimDebug:Show, w378 h56 y600
    WinSet,AlwaysOnTop,On,ahk_id %_vimdebug%
    }
    Else
    {
		  GUI,vimDebug:font,s12
		  GUI,vimDebug:Destroy
		  GUI,vimDebug:Add,Edit,x10 y10 w400 h300 readonly
		  GUI,vimDebug:Add,Edit,x10 y320 w400 h26 readonly
		  GUI,vimDebug:Show, w420 h356
    }
	}
  var(obj)
  {
    this.vim := obj
  }
	Set(v)
	{
    winName := this.vim.CheckWin()
    winObj := this.vim.GetWin(winName)
    If winObj.Count
			 k := " 热键缓存:" winObj.Count winObj.KeyTemp
    Else
			 k := " 热键缓存:" winObj.KeyTemp
		GUI,vimDebug:Default
		GUIControl,,Edit1,%v%
		GUIControl,,Edit2,%k%
	}
	Get()
	{
		GUI,vimDebug:Default
		GUIControlGet,v,,Edit1
		return v
	}
	; Add(v) {{{2
	Add(v)
	{
		b:=this.Get()
    If this.mode
		  this.Set(b)
    else
		  this.Set(v "`n" b)
	}
	; Clear() {{{2
	Clear()
	{
		this.Set("")
	}
}


update movement script

update movement script

DetectHiddenWindows, On
SetDefaultMouseSpeed, 0
CoordMode, Mouse, Client
target=ahk_class Diablo II

if (%0% < 4 || %0% == "") {
    loops = 1
} else {
    loops = %4%
}

WinGet, hwnd, ID, %target%
if (hwnd) {
    WinActivate, ahk_id %hwnd%
    IfWinActive, ahk_id %hwnd%
    {
        ;BlockInput On
        ; move mouse once and click after, so we can have new directional input while this runs
        MouseMove, %1%, %2%, 0
        Loop %loops% {
            ; only click if the window is active right now
            IfWinActive, ahk_id %hwnd%
            {
                MouseClick, %3%, , , , 0
            }
            Sleep 250
        }
        ;BlockInput Off
    }
}

DetectHiddenWindows, On
SetDefaultMouseSpeed, 0
CoordMode, Mouse, Client
target=ahk_class Diablo II

if (%0% < 4 || %0% == "") {
    loops = 1
} else {
    loops = %4%
}

WinGet, hwnd, ID, %target%
if (hwnd) {
    WinActivate, ahk_id %hwnd%
    IfWinActive, ahk_id %hwnd%
    {
        BlockInput On
        Loop %loops% {
            MouseMove, %1%, %2%, 0
            ;if (%A_Index% == %loops%) {
                MouseClick, %3%, , , , 0
                Sleep 250
            ;} else {
            ;    MouseClick, %3%, , , , 0, D
            ;    Sleep 250
            ;    MouseClick, %3%, , , , 0, U
            ;    Sleep 50
            ;}
        }
        BlockInput Off
    }
}


fixed autohotkey shortcuts

fixed autohotkey shortcuts

#SingleInstance force

; Common Key for sendinput
; !{key} -> Alt + {key}
; ^{key} -> Ctrl + {key}
;

#Include *i %A_MyDocuments%\AutoHotKeyU64_WorkSpecific.ahk

#j::
  Run notepad "%A_MyDocuments%\AutoHotKeyU64.ahk" ; "C:\Program Files (x86)\Vim\vim74\gvim.exe"
  Sleep 5000
  WinActivate, AutoHotKeyU64.ahk - Notepad
return

#u::
  Run notepad "%A_MyDocuments%\AutoHotKeyU64_WorkSpecific.ahk" ; "C:\Program Files (x86)\Vim\vim74\gvim.exe"
  Sleep 5000
  WinActivate, AutoHotKeyU64
return

#k::
  Reload
  Sleep 2000 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
  MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing?
  IfMsgBox, Yes, Edit
return

#t::Run "C:\Program Files\ConEmu\ConEmu64.exe"
#p::SendInput . C:\Users\andlam\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1{Enter}

; Remap the windows movement to only require ctrl and not the winkey
;#9::SendInput,{Ctrl down}{LWin down}{Left}{Ctrl up}{LWin up}
;#0::SendInput,{Ctrl down}{LWin down}{Right}{Ctrl up}{LWin up}
;!Left::^#Left
;!Right::^#Right
Alt & 0::AltTab
Alt & 9::ShiftAltTab
;Ctrl & 0::SendInput {Ctrl down}{Tab}{Ctrl up}
;Ctrl & 9::SendInput {Ctrl down}{Shift down}{Tab}{Shift up}{Ctrl up}

Alt & -::AltTabMenuDismiss

!Numpad0::SendInput {Media_Play_Pause}
!NumpadIns::SendInput {Media_Play_Pause}
!Numpad4::SendInput {Media_Prev}
!NumpadLeft::SendInput {Media_Prev}
!Numpad6::SendInput {Media_Next}
!NumpadRight::SendInput {Media_Next}
!NumpadAdd::SoundSet +5
!NumpadSub::SoundSet -5

#SingleInstance force

; Common Key for sendinput
; !{key} -> Alt + {key}
; ^{key} -> Ctrl + {key}
;

#Include *i %A_MyDocuments%\AutoHotKeyU64_WorkSpecific.ahk

#h::
  Run notepad "%A_MyDocuments%\AutoHotKeyU64.ahk" ; "C:\Program Files (x86)\Vim\vim74\gvim.exe"
  Sleep 5000
  WinActivate, AutoHotKeyU64.ahk - Notepad
return

#y::
  Run notepad "%A_MyDocuments%\AutoHotKeyU64_WorkSpecific.ahk" ; "C:\Program Files (x86)\Vim\vim74\gvim.exe"
  Sleep 5000
  WinActivate, AutoHotKeyU64
return

#j::
  Reload
  Sleep 2000 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
  MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing?
  IfMsgBox, Yes, Edit
return

#t::Run "C:\Program Files\ConEmu\ConEmu64.exe"
#p::SendInput . C:\Users\andlam\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1{Enter}

; Remap the windows movement to only require ctrl and not the winkey
;#9::SendInput,{Ctrl down}{LWin down}{Left}{Ctrl up}{LWin up}
;#0::SendInput,{Ctrl down}{LWin down}{Right}{Ctrl up}{LWin up}
;!Left::^#Left
;!Right::^#Right
Alt & 0::AltTab
Alt & 9::ShiftAltTab
;Ctrl & 0::SendInput {Ctrl down}{Tab}{Ctrl up}
;Ctrl & 9::SendInput {Ctrl down}{Shift down}{Tab}{Shift up}{Ctrl up}

Alt & -::AltTabMenuDismiss

!Numpad0::SendInput {Media_Play_Pause}
!NumpadIns::SendInput {Media_Play_Pause}
!Numpad4::SendInput {Media_Prev}
!NumpadLeft::SendInput {Media_Prev}
!Numpad6::SendInput {Media_Next}
!NumpadRight::SendInput {Media_Next}
!NumpadAdd::SoundSet +5
!NumpadSub::SoundSet -5


added media keys to ahk

added media keys to ahk

#SingleInstance force

; Common Key for sendinput
; !{key} -> Alt + {key}
; ^{key} -> Ctrl + {key}
;

#Include *i %A_MyDocuments%\AutoHotKeyU64_WorkSpecific.ahk

#h::
  Run notepad "%A_MyDocuments%\AutoHotKeyU64.ahk" ; "C:\Program Files (x86)\Vim\vim74\gvim.exe"
  Sleep 5000
  WinActivate, AutoHotKeyU64.ahk - Notepad
return

#y::
  Run notepad "%A_MyDocuments%\AutoHotKeyU64_WorkSpecific.ahk" ; "C:\Program Files (x86)\Vim\vim74\gvim.exe"
  Sleep 5000
  WinActivate, AutoHotKeyU64
return

#j::
  Reload
  Sleep 2000 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
  MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing?
  IfMsgBox, Yes, Edit
return

#t::Run "C:\Program Files\ConEmu\ConEmu64.exe"
#p::SendInput . C:\Users\andlam\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1{Enter}

; Remap the windows movement to only require ctrl and not the winkey
;#9::SendInput,{Ctrl down}{LWin down}{Left}{Ctrl up}{LWin up}
;#0::SendInput,{Ctrl down}{LWin down}{Right}{Ctrl up}{LWin up}
;!Left::^#Left
;!Right::^#Right
Alt & 0::AltTab
Alt & 9::ShiftAltTab
;Ctrl & 0::SendInput {Ctrl down}{Tab}{Ctrl up}
;Ctrl & 9::SendInput {Ctrl down}{Shift down}{Tab}{Shift up}{Ctrl up}

Alt & -::AltTabMenuDismiss

!Numpad0::SendInput {Media_Play_Pause}
!NumpadIns::SendInput {Media_Play_Pause}
!Numpad4::SendInput {Media_Prev}
!NumpadLeft::SendInput {Media_Prev}
!Numpad6::SendInput {Media_Next}
!NumpadRight::SendInput {Media_Next}
!NumpadAdd::SoundSet +5
!NumpadSub::SoundSet -5


Add result to KillProcess

Add result to KillProcess

; RunZ:Core
; 核心功能

Core:
    @("Help", "帮助信息")
    @("KeyHelp", "置顶的按键帮助信息")
    @("AhkRun", "使用 Ahk 的 Run() 运行 `; command", true)
    @("CmdRun", "使用 cmd 运行 : command", true)
    @("CmdRunOnly", "只使用 cmd 运行")
    @("WinRRun", "使用 win + r 运行", true)
    @("RunAndDisplay", "使用 cmd 运行，并显示结果", true)
    @("ReindexFiles", "重新索引待搜索文件")
    @("Clip", "显示剪切板内容")
    @("EditConfig", "编辑配置文件")
    @("ClearClipboardFormat", "清除剪切板中文字的格式")
    @("RunClipboard", "使用 ahk 的 Run 运行剪切板内容")
    @("EmptyRecycle", "清空回收站")
    @("Logoff", "注销 登出")
    @("RestartMachine", "重启")
    @("ShutdownMachine", "关机")
    @("SuspendMachine", "挂起 睡眠 待机")
    @("HibernateMachine", "休眠")
    @("TurnMonitorOff", "关闭显示器")
    @("CleanupRank", "清理命令权重中的无效命令")
    @("ListProcess", "列出进程 ps")
    @("DiskSpace", "查看磁盘空间 df")
    @("ArgTest", "参数测试：ArgTest arg1 arg2 ...")
    @("AhkTest", "运行参数或者剪切板中的 AHK 代码")
    @("IncreaseVolume", "提高音量")
    @("DecreaseVolume", "降低音量")
    @("SystemState", "系统状态 top")
    @("KillProcess", "杀死进程")
    @("SendToClip", "发送到剪切板")
    @("ListWindow", "窗口列表")
    @("ActivateWindow", "激活窗口")
    @("InstallPlugin", "安装插件")
    @("RemovePlugin", "卸载插件")
    @("ListPlugin", "列出插件")
    @("CleanupPlugin", "清理插件")
    @("CountNumber", "计算数量 wc")
    @("ListRunningService", "列出运行的服务")
    @("ListAllService", "列出运行的服务")
    @("ShowService", "显示服务详情")
    @("ShowProcess", "显示进程详情")
return

CmdRun:
    RunWithCmd(Arg)
return

CmdRunOnly:
    RunWithCmd(Arg, true)
return

AhkRun:
    Run, %Arg%
return

Clip:
    GoSub, ActivateRunZ
    DisplayResult("剪切板内容长度 " . StrLen(clipboard) . " ：`n`n" . clipboard)
return

ArgTest:
    args := StrSplit(Arg, " ")
    result := "共有 " . args.Length() . " 个参数。`n`n"

    for index, argument in args
    {
        result .= "第 " . index . " 个参数：" . argument . "`n"
    }

    DisplayResult(result)
return

ClearClipboardFormat:
    clipboard := clipboard
return

RunClipboard:
    Run, %clipboard%
return

RunAndDisplay:
    DisplayResult(RunAndGetOutput(Arg))
return

WinRRun:
    Send, #r
    Sleep, 100
    Send, %Arg%
    Send, {enter}
return

Logoff:
    MsgBox, 4, , 将要注销，是否执行？
    IfMsgBox Yes
    {
        Shutdown, 0
    }
return

ShutdownMachine:
    MsgBox, 4, , 将要关机，是否执行？
    IfMsgBox Yes
    {
        Shutdown, 1
    }
return

RestartMachine:
    MsgBox, 4, , 将要重启机器，是否执行？
    IfMsgBox Yes
    {
        Shutdown, 2
    }
return

HibernateMachine:
    MsgBox, 4, , 将要休眠，是否执行？
    IfMsgBox Yes
    {
        ; 参数 #1: 使用 1 代替 0 来进行休眠而不是挂起。
        ; 参数 #2: 使用 1 代替 0 来立即挂起而不询问每个应用程序以获得许可。
        ; 参数 #3: 使用 1 而不是 0 来禁止所有的唤醒事件。
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
    }
return

SuspendMachine:
    MsgBox, 4, , 将要待机，是否执行？
    IfMsgBox Yes
    {
        DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
    }
return

TurnMonitorOff:
    ; 关闭显示器:
    SendMessage, 0x112, 0xF170, 2,, Program Manager
    ; 0x112 is WM_SYSCOMMAND, 0xF170 is SC_MONITORPOWER.
    ; 对上面命令的注释: 使用 -1 代替 2 来打开显示器.
    ; 使用 1 代替 2 来激活显示器的节能模式.
return

EmptyRecycle:
    MsgBox, 4, , 将要清空回收站，是否执行？
    IfMsgBox Yes
    {
        FileRecycleEmpty,
    }
return

ListProcess:
    result := ""

    for process in ComObjGet("winmgmts:").ExecQuery("select * from Win32_Process")
    {
        result .= "* | 进程 | " process.Name " | " process.CommandLine "`n"
    }
    Sort, result

    SetCommandFilter("KillProcess|ShowProcess|CountNumber")
    DisplayResult(FilterResult(AlignText(result), Arg))
    TurnOnResultFilter()
return

DiskSpace:
    result := ""

    DriveGet, list, list
    Loop, Parse, list
    {
        drive := A_LoopField ":"
        DriveGet, label, label, %drive%
        DriveGet, cap, capacity, %drive%
        DrivespaceFree, free, %drive%
        SetFormat, float, 5.2
        percent := 100 * (cap - free) / cap
        SetFormat, float, 6.2
        cap /= 1024.0
        free /= 1024.0
        result = %result%* | %drive% | 总共: %cap% G  可用: %free% G | 已使用：%percent%`%  卷标: %label%`n
    }

    DisplayResult(AlignText(result))
return

AhkTest:
    text := Arg == "" ? clipboard : Arg
    FileDelete, %A_Temp%\RunZ.AhkTest.ahk
    FileAppend, %text%, %A_Temp%\RunZ.AhkTest.ahk
    Run, %A_Temp%\RunZ.AhkTest.ahk
return

IncreaseVolume:
    SoundSet, +5
return

DecreaseVolume:
    SoundSet, -5
return

SystemState:
    if (!SetExecInterval(1))
    {
        return
    }

    GMSEx := GlobalMemoryStatusEx()
    result := "* | 状态 | 运行时间 | " Round(A_TickCount / 1000 / 3600, 3) " 小时`n"
    result .= "* | 状态 | CPU 占用 | " CPULoad() "% `n"
    result .= "* | 状态 | 内存占用 | " Round(100 * (GMSEx[2] - GMSEx[3]) / GMSEx[2], 2) "% `n"
    result .= "* | 状态 | 进程总数 | " GetProcessCount() "`n"
    result .= "* | 状态 | 内存总量 | " Round(GMSEx[2] / 1024**2, 2) "MB `n"
    result .= "* | 状态 | 可用内存 | " Round(GMSEx[3] / 1024**2, 2) "MB `n"
    DisplayResult(AlignText(result))
return

KillProcess:
    args := StrSplit(Arg, " ")
    for index, argument in args
    {
        Process, Close, %argument%
    }

    DisplayResult("已尝试杀死 " Arg " 进程")
return

SendToClip:
    clipboard := Arg
    GoSub, Clip
return

ListWindow:
    result := ""

    WinGet, id, list, , , Program Manager
    Loop, %id%
    {
        thisId := id%A_Index%
        WinGetTitle, title, ahk_id %thisId%
        WinGet, name, ProcessName, ahk_id %thisId%
        if (title == "")
        {
            continue
        }
        result .= "* | 窗口 | " name " | " title "`n"
    }

    SetCommandFilter("ActivateWindow|KillProcess")
    DisplayResult(AlignText(result))
    TurnOnResultFilter()
return

ActivateWindow:
    DisplayResult()
    ClearInput()

    if (FullPipeArg != "")
    {
        Loop, Parse, FullPipeArg, `n, `r
        {
            if (A_LoopField == "")
            {
                return
            }
            splitedLine := StrSplit(A_LoopField, " | ")
            WinActivate, % Trim(splitedLine[4])
        }
    }
    else
    {
        for index, argument in StrSplit(Arg, " ")
        {
            WinActivate, ahk_exe %argument%
        }
    }
return

InstallPlugin:
    pluginPath := Arg

    if (InStr(pluginPath, "http") == 1)
    {
        DisplayResult("下载中，请稍后...")
        UrlDownloadToFile, %pluginPath%, %A_Temp%\RunZ.Plugin.txt
        pluginPath := A_Temp "\RunZ.Plugin.txt"
    }

    if (FileExist(pluginPath))
    {
        FileReadLine, firstLine, %pluginPath%, 1
        if (!InStr(firstLine, "; RunZ:"))
        {
            DisplayResult(pluginPath " 并不是有效的 RunZ 插件")
            return
        }

        pluginName := StrSplit(firstLine, "; RunZ:")[2]
        if (FileExist(A_ScriptDir "\Plugins\" pluginName ".ahk"))
        {
            DisplayResult("该插件已存在")
            return
        }

        FileMove, %pluginPath%, %A_ScriptDir%\Plugins\%pluginName%.ahk
        FileAppend, #include *i `%A_ScriptDir`%\Plugins\%pluginName%.ahk`n
            , %A_ScriptDir%\Core\Plugins.ahk

        DisplayResult(pluginName " 插件安装成功，RunZ 将重启并启用该插件")
        Sleep, 1000
        GoSub, RestartRunZ
    }
    else
    {
        DisplayResult(pluginPath " 文件不存在")
    }
return

RemovePlugin:
    pluginName := Arg
    if (!FileExist(A_ScriptDir "\Plugins\" pluginName ".ahk"))
    {
        DisplayResult("未安装该插件")
        return
    }

    FileRead, currentPlugins, %A_ScriptDir%\Core\Plugins.ahk
    StringReplace, currentPlugins, currentPlugins
        , #include *i `%A_ScriptDir`%\Plugins\%pluginName%.ahk`r`n
    FileDelete, %A_ScriptDir%\Core\Plugins.ahk
    FileAppend, %currentPlugins%, %A_ScriptDir%\Core\Plugins.ahk
    FileDelete, %A_ScriptDir%\Plugins\%pluginName%.ahk

    DisplayResult(pluginName " 插件删除成功，RunZ 将重启以生效")
    Sleep, 1000
    GoSub, RestartRunZ
return

ListPlugin:
    result := ""
    Loop, Files, %A_ScriptDir%\Plugins\*.ahk
    {
        pluginName := StrReplace(A_LoopFileName, ".ahk")
        FileReadLine, secondLine, %A_LoopFileLongPath%, 2
        if (g_Conf.GetValue("Plugins", pluginName) == 0)
        {
            result .= "* | 插件 | " pluginName " | 已禁用  描述：" SubStr(secondLine, 3) "`n"
        }
        else
        {
            result .= "* | 插件 | " pluginName " | 已启用  描述：" SubStr(secondLine, 3) "`n"
        }
    }

    DisplayResult(AlignText(result))
    TurnOnResultFilter()
    SetCommandFilter("RemovePlugin")
return

CleanupPlugin:
    result := ""
    FileRead, currentPlugins, %A_ScriptDir%\Core\Plugins.ahk
    Loop, Parse, currentPlugins, `n, `r
    {
        SplitPath, A_LoopField , , , , pluginName,
        if (g_Conf.GetValue("Plugins", pluginName) == 0)
        {
            result .= pluginName " 插件已被清理，下次运行 RunZ 将不再引入`n"
            StringReplace, currentPlugins, currentPlugins
                , #include *i `%A_ScriptDir`%\Plugins\%pluginName%.ahk`r`n
        }
    }

    if (result != "")
    {
        DisplayResult(result)
        FileDelete, %A_ScriptDir%\Core\Plugins.ahk
        FileAppend, %currentPlugins%, %A_ScriptDir%\Core\Plugins.ahk
    }
    else
    {
        DisplayResult("无可清理插件")
    }
return

CountNumber:
    result := "* | 数量 | " StrSplit(Arg, " ").Length() " | 以空格为分隔符`n"
    if (SubStr(FullPipeArg, 0, -1) = "`n")
    {
        result .= "* | 数量 | " StrSplit(FullPipeArg, "`n").Length()  - 1 " | 以换行为分隔符`n"
    }
    else
    {
        result .= "* | 数量 | " StrSplit(FullPipeArg, "`n").Length() " | 以换行为分隔符`n"
    }

    DisplayResult(AlignText(result))
return

ListAllService:
    result :=
    for service in ComObjGet("winmgmts:").ExecQuery("select * from Win32_Service")
    {
        result .= "* | 服务 | " service.Name " | " service.DisplayName "`n"
    }
    Sort, result

    SetCommandFilter("CountNumber|ShowService")
    DisplayResult(FilterResult(AlignText(result), Arg))
    TurnOnResultFilter()
return

ListRunningService:
    result :=
    for service in ComObjGet("winmgmts:").ExecQuery("select * from Win32_Service")
    {
        if (service.Started != 0)
        {
            result .= "* | 服务 | " service.Name " | " service.DisplayName "`n"
        }
    }
    Sort, result

    SetCommandFilter("CountNumber|ShowService")
    DisplayResult(FilterResult(AlignText(result), Arg))
    TurnOnResultFilter()
return

ShowService:
    result :=
    ; 暂时只支持一个，选得多了查起来太慢
    for service in ComObjGet("winmgmts:")
        .ExecQuery("select * from Win32_Service where Name = '" StrSplit(Arg, " ")[1] "'")
    {
        ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa394418%28v=vs.85%29.aspx
        result .= "* | 服务 | 名称 | " service.Name "`n"
        result .= "* | 服务 | 描述 | " service.Description "`n"
        result .= "* | 服务 | 是否在运行 | " service.Started "`n"
        result .= "* | 服务 | 路径 | " service.PathName "`n"
        result .= "* | 服务 | 进程 ID | " service.ProcessId "`n"
        result .= "* | 服务 | 类型 | " service.ServiceType "`n"
        break
    }

    DisplayResult(AlignText(result))
return

ShowProcess:
    result :=
    ; 暂时只支持一个，选得多了查起来太慢
    for process in ComObjGet("winmgmts:")
        .ExecQuery("select * from Win32_Process where Name = '" StrSplit(Arg, " ")[1] "'")
    {
        ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa394372%28v=vs.85%29.aspx
        result .= "* | 服务 | 名称 | " process.Name "`n"
        result .= "* | 服务 | 描述 | " process.Description "`n"
        result .= "* | 服务 | 命令行 | " process.CommandLine "`n"
        result .= "* | 服务 | 启动时间 | " process.CreationDate "`n"
        result .= "* | 服务 | ID | " process.ProcessId "`n"
        break
    }

    DisplayResult(AlignText(result))
return

; RunZ:Core
; 核心功能

Core:
    @("Help", "帮助信息")
    @("KeyHelp", "置顶的按键帮助信息")
    @("AhkRun", "使用 Ahk 的 Run() 运行 `; command", true)
    @("CmdRun", "使用 cmd 运行 : command", true)
    @("CmdRunOnly", "只使用 cmd 运行")
    @("WinRRun", "使用 win + r 运行", true)
    @("RunAndDisplay", "使用 cmd 运行，并显示结果", true)
    @("ReindexFiles", "重新索引待搜索文件")
    @("Clip", "显示剪切板内容")
    @("EditConfig", "编辑配置文件")
    @("ClearClipboardFormat", "清除剪切板中文字的格式")
    @("RunClipboard", "使用 ahk 的 Run 运行剪切板内容")
    @("EmptyRecycle", "清空回收站")
    @("Logoff", "注销 登出")
    @("RestartMachine", "重启")
    @("ShutdownMachine", "关机")
    @("SuspendMachine", "挂起 睡眠 待机")
    @("HibernateMachine", "休眠")
    @("TurnMonitorOff", "关闭显示器")
    @("CleanupRank", "清理命令权重中的无效命令")
    @("ListProcess", "列出进程 ps")
    @("DiskSpace", "查看磁盘空间 df")
    @("ArgTest", "参数测试：ArgTest arg1 arg2 ...")
    @("AhkTest", "运行参数或者剪切板中的 AHK 代码")
    @("IncreaseVolume", "提高音量")
    @("DecreaseVolume", "降低音量")
    @("SystemState", "系统状态 top")
    @("KillProcess", "杀死进程")
    @("SendToClip", "发送到剪切板")
    @("ListWindow", "窗口列表")
    @("ActivateWindow", "激活窗口")
    @("InstallPlugin", "安装插件")
    @("RemovePlugin", "卸载插件")
    @("ListPlugin", "列出插件")
    @("CleanupPlugin", "清理插件")
    @("CountNumber", "计算数量 wc")
    @("ListRunningService", "列出运行的服务")
    @("ListAllService", "列出运行的服务")
    @("ShowService", "显示服务详情")
    @("ShowProcess", "显示进程详情")
return

CmdRun:
    RunWithCmd(Arg)
return

CmdRunOnly:
    RunWithCmd(Arg, true)
return

AhkRun:
    Run, %Arg%
return

Clip:
    GoSub, ActivateRunZ
    DisplayResult("剪切板内容长度 " . StrLen(clipboard) . " ：`n`n" . clipboard)
return

ArgTest:
    args := StrSplit(Arg, " ")
    result := "共有 " . args.Length() . " 个参数。`n`n"

    for index, argument in args
    {
        result .= "第 " . index . " 个参数：" . argument . "`n"
    }

    DisplayResult(result)
return

ClearClipboardFormat:
    clipboard := clipboard
return

RunClipboard:
    Run, %clipboard%
return

RunAndDisplay:
    DisplayResult(RunAndGetOutput(Arg))
return

WinRRun:
    Send, #r
    Sleep, 100
    Send, %Arg%
    Send, {enter}
return

Logoff:
    MsgBox, 4, , 将要注销，是否执行？
    IfMsgBox Yes
    {
        Shutdown, 0
    }
return

ShutdownMachine:
    MsgBox, 4, , 将要关机，是否执行？
    IfMsgBox Yes
    {
        Shutdown, 1
    }
return

RestartMachine:
    MsgBox, 4, , 将要重启机器，是否执行？
    IfMsgBox Yes
    {
        Shutdown, 2
    }
return

HibernateMachine:
    MsgBox, 4, , 将要休眠，是否执行？
    IfMsgBox Yes
    {
        ; 参数 #1: 使用 1 代替 0 来进行休眠而不是挂起。
        ; 参数 #2: 使用 1 代替 0 来立即挂起而不询问每个应用程序以获得许可。
        ; 参数 #3: 使用 1 而不是 0 来禁止所有的唤醒事件。
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
    }
return

SuspendMachine:
    MsgBox, 4, , 将要待机，是否执行？
    IfMsgBox Yes
    {
        DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
    }
return

TurnMonitorOff:
    ; 关闭显示器:
    SendMessage, 0x112, 0xF170, 2,, Program Manager
    ; 0x112 is WM_SYSCOMMAND, 0xF170 is SC_MONITORPOWER.
    ; 对上面命令的注释: 使用 -1 代替 2 来打开显示器.
    ; 使用 1 代替 2 来激活显示器的节能模式.
return

EmptyRecycle:
    MsgBox, 4, , 将要清空回收站，是否执行？
    IfMsgBox Yes
    {
        FileRecycleEmpty,
    }
return

ListProcess:
    result := ""

    for process in ComObjGet("winmgmts:").ExecQuery("select * from Win32_Process")
    {
        result .= "* | 进程 | " process.Name " | " process.CommandLine "`n"
    }
    Sort, result

    SetCommandFilter("KillProcess|ShowProcess|CountNumber")
    DisplayResult(FilterResult(AlignText(result), Arg))
    TurnOnResultFilter()
return

DiskSpace:
    result := ""

    DriveGet, list, list
    Loop, Parse, list
    {
        drive := A_LoopField ":"
        DriveGet, label, label, %drive%
        DriveGet, cap, capacity, %drive%
        DrivespaceFree, free, %drive%
        SetFormat, float, 5.2
        percent := 100 * (cap - free) / cap
        SetFormat, float, 6.2
        cap /= 1024.0
        free /= 1024.0
        result = %result%* | %drive% | 总共: %cap% G  可用: %free% G | 已使用：%percent%`%  卷标: %label%`n
    }

    DisplayResult(AlignText(result))
return

AhkTest:
    text := Arg == "" ? clipboard : Arg
    FileDelete, %A_Temp%\RunZ.AhkTest.ahk
    FileAppend, %text%, %A_Temp%\RunZ.AhkTest.ahk
    Run, %A_Temp%\RunZ.AhkTest.ahk
return

IncreaseVolume:
    SoundSet, +5
return

DecreaseVolume:
    SoundSet, -5
return

SystemState:
    if (!SetExecInterval(1))
    {
        return
    }

    GMSEx := GlobalMemoryStatusEx()
    result := "* | 状态 | 运行时间 | " Round(A_TickCount / 1000 / 3600, 3) " 小时`n"
    result .= "* | 状态 | CPU 占用 | " CPULoad() "% `n"
    result .= "* | 状态 | 内存占用 | " Round(100 * (GMSEx[2] - GMSEx[3]) / GMSEx[2], 2) "% `n"
    result .= "* | 状态 | 进程总数 | " GetProcessCount() "`n"
    result .= "* | 状态 | 内存总量 | " Round(GMSEx[2] / 1024**2, 2) "MB `n"
    result .= "* | 状态 | 可用内存 | " Round(GMSEx[3] / 1024**2, 2) "MB `n"
    DisplayResult(AlignText(result))
return

KillProcess:
    args := StrSplit(Arg, " ")
    for index, argument in args
    {
        Process, Close, %argument%
    }
return

SendToClip:
    clipboard := Arg
    GoSub, Clip
return

ListWindow:
    result := ""

    WinGet, id, list, , , Program Manager
    Loop, %id%
    {
        thisId := id%A_Index%
        WinGetTitle, title, ahk_id %thisId%
        WinGet, name, ProcessName, ahk_id %thisId%
        if (title == "")
        {
            continue
        }
        result .= "* | 窗口 | " name " | " title "`n"
    }

    SetCommandFilter("ActivateWindow|KillProcess")
    DisplayResult(AlignText(result))
    TurnOnResultFilter()
return

ActivateWindow:
    DisplayResult()
    ClearInput()

    if (FullPipeArg != "")
    {
        Loop, Parse, FullPipeArg, `n, `r
        {
            if (A_LoopField == "")
            {
                return
            }
            splitedLine := StrSplit(A_LoopField, " | ")
            WinActivate, % Trim(splitedLine[4])
        }
    }
    else
    {
        for index, argument in StrSplit(Arg, " ")
        {
            WinActivate, ahk_exe %argument%
        }
    }
return

InstallPlugin:
    pluginPath := Arg

    if (InStr(pluginPath, "http") == 1)
    {
        DisplayResult("下载中，请稍后...")
        UrlDownloadToFile, %pluginPath%, %A_Temp%\RunZ.Plugin.txt
        pluginPath := A_Temp "\RunZ.Plugin.txt"
    }

    if (FileExist(pluginPath))
    {
        FileReadLine, firstLine, %pluginPath%, 1
        if (!InStr(firstLine, "; RunZ:"))
        {
            DisplayResult(pluginPath " 并不是有效的 RunZ 插件")
            return
        }

        pluginName := StrSplit(firstLine, "; RunZ:")[2]
        if (FileExist(A_ScriptDir "\Plugins\" pluginName ".ahk"))
        {
            DisplayResult("该插件已存在")
            return
        }

        FileMove, %pluginPath%, %A_ScriptDir%\Plugins\%pluginName%.ahk
        FileAppend, #include *i `%A_ScriptDir`%\Plugins\%pluginName%.ahk`n
            , %A_ScriptDir%\Core\Plugins.ahk

        DisplayResult(pluginName " 插件安装成功，RunZ 将重启并启用该插件")
        Sleep, 1000
        GoSub, RestartRunZ
    }
    else
    {
        DisplayResult(pluginPath " 文件不存在")
    }
return

RemovePlugin:
    pluginName := Arg
    if (!FileExist(A_ScriptDir "\Plugins\" pluginName ".ahk"))
    {
        DisplayResult("未安装该插件")
        return
    }

    FileRead, currentPlugins, %A_ScriptDir%\Core\Plugins.ahk
    StringReplace, currentPlugins, currentPlugins
        , #include *i `%A_ScriptDir`%\Plugins\%pluginName%.ahk`r`n
    FileDelete, %A_ScriptDir%\Core\Plugins.ahk
    FileAppend, %currentPlugins%, %A_ScriptDir%\Core\Plugins.ahk
    FileDelete, %A_ScriptDir%\Plugins\%pluginName%.ahk

    DisplayResult(pluginName " 插件删除成功，RunZ 将重启以生效")
    Sleep, 1000
    GoSub, RestartRunZ
return

ListPlugin:
    result := ""
    Loop, Files, %A_ScriptDir%\Plugins\*.ahk
    {
        pluginName := StrReplace(A_LoopFileName, ".ahk")
        FileReadLine, secondLine, %A_LoopFileLongPath%, 2
        if (g_Conf.GetValue("Plugins", pluginName) == 0)
        {
            result .= "* | 插件 | " pluginName " | 已禁用  描述：" SubStr(secondLine, 3) "`n"
        }
        else
        {
            result .= "* | 插件 | " pluginName " | 已启用  描述：" SubStr(secondLine, 3) "`n"
        }
    }

    DisplayResult(AlignText(result))
    TurnOnResultFilter()
    SetCommandFilter("RemovePlugin")
return

CleanupPlugin:
    result := ""
    FileRead, currentPlugins, %A_ScriptDir%\Core\Plugins.ahk
    Loop, Parse, currentPlugins, `n, `r
    {
        SplitPath, A_LoopField , , , , pluginName,
        if (g_Conf.GetValue("Plugins", pluginName) == 0)
        {
            result .= pluginName " 插件已被清理，下次运行 RunZ 将不再引入`n"
            StringReplace, currentPlugins, currentPlugins
                , #include *i `%A_ScriptDir`%\Plugins\%pluginName%.ahk`r`n
        }
    }

    if (result != "")
    {
        DisplayResult(result)
        FileDelete, %A_ScriptDir%\Core\Plugins.ahk
        FileAppend, %currentPlugins%, %A_ScriptDir%\Core\Plugins.ahk
    }
    else
    {
        DisplayResult("无可清理插件")
    }
return

CountNumber:
    result := "* | 数量 | " StrSplit(Arg, " ").Length() " | 以空格为分隔符`n"
    if (SubStr(FullPipeArg, 0, -1) = "`n")
    {
        result .= "* | 数量 | " StrSplit(FullPipeArg, "`n").Length()  - 1 " | 以换行为分隔符`n"
    }
    else
    {
        result .= "* | 数量 | " StrSplit(FullPipeArg, "`n").Length() " | 以换行为分隔符`n"
    }

    DisplayResult(AlignText(result))
return

ListAllService:
    result :=
    for service in ComObjGet("winmgmts:").ExecQuery("select * from Win32_Service")
    {
        result .= "* | 服务 | " service.Name " | " service.DisplayName "`n"
    }
    Sort, result

    SetCommandFilter("CountNumber|ShowService")
    DisplayResult(FilterResult(AlignText(result), Arg))
    TurnOnResultFilter()
return

ListRunningService:
    result :=
    for service in ComObjGet("winmgmts:").ExecQuery("select * from Win32_Service")
    {
        if (service.Started != 0)
        {
            result .= "* | 服务 | " service.Name " | " service.DisplayName "`n"
        }
    }
    Sort, result

    SetCommandFilter("CountNumber|ShowService")
    DisplayResult(FilterResult(AlignText(result), Arg))
    TurnOnResultFilter()
return

ShowService:
    result :=
    ; 暂时只支持一个，选得多了查起来太慢
    for service in ComObjGet("winmgmts:")
        .ExecQuery("select * from Win32_Service where Name = '" StrSplit(Arg, " ")[1] "'")
    {
        ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa394418%28v=vs.85%29.aspx
        result .= "* | 服务 | 名称 | " service.Name "`n"
        result .= "* | 服务 | 描述 | " service.Description "`n"
        result .= "* | 服务 | 是否在运行 | " service.Started "`n"
        result .= "* | 服务 | 路径 | " service.PathName "`n"
        result .= "* | 服务 | 进程 ID | " service.ProcessId "`n"
        result .= "* | 服务 | 类型 | " service.ServiceType "`n"
        break
    }

    DisplayResult(AlignText(result))
return

ShowProcess:
    result :=
    ; 暂时只支持一个，选得多了查起来太慢
    for process in ComObjGet("winmgmts:")
        .ExecQuery("select * from Win32_Process where Name = '" StrSplit(Arg, " ")[1] "'")
    {
        ; https://msdn.microsoft.com/en-us/library/windows/desktop/aa394372%28v=vs.85%29.aspx
        result .= "* | 服务 | 名称 | " process.Name "`n"
        result .= "* | 服务 | 描述 | " process.Description "`n"
        result .= "* | 服务 | 命令行 | " process.CommandLine "`n"
        result .= "* | 服务 | 启动时间 | " process.CreationDate "`n"
        result .= "* | 服务 | ID | " process.ProcessId "`n"
        break
    }

    DisplayResult(AlignText(result))
return


background sound on

background sound on

DetectHiddenWindows, On
SetDefaultMouseSpeed, 0
CoordMode, Mouse, Client
target=ahk_class Diablo II
executeCmd=Diablo II.exe -w -sndbkg
executeDir=C:\Diablo II
SetWorkingDir, %executeDir%

WinGet, hwnd, ID, %target%
if (!hwnd) {
    Run, %executeCmd%
    Sleep, 5000
    WinGet, hwnd, ID, %target%
    if (hwnd) {
        WinSet, AlwaysOnTop, on, ahk_id %hwnd%
        WinActivate, ahk_id %hwnd%
        IfWinActive, ahk_id %hwnd%
        {
            BlockInput On
            MouseMove, 400, 308, 0
            MouseClick, left
            Sleep, 500
            MouseClick, left
            Sleep, 5000
            MouseMove, 175, 125, 0
            MouseClick, left
            MouseClick, left
            Sleep, 500
            MouseClick, left
            MouseClick, left
            Sleep, 5000
            BlockInput Off
        }
    }
}

DetectHiddenWindows, On
SetDefaultMouseSpeed, 0
CoordMode, Mouse, Client
target=ahk_class Diablo II
executeCmd=Diablo II.exe -w
executeDir=C:\Diablo II
SetWorkingDir, %executeDir%

WinGet, hwnd, ID, %target%
if (!hwnd) {
    Run, %executeCmd%
    Sleep, 5000
    WinGet, hwnd, ID, %target%
    if (hwnd) {
        WinSet, AlwaysOnTop, on, ahk_id %hwnd%
        WinActivate, ahk_id %hwnd%
        IfWinActive, ahk_id %hwnd%
        {
            BlockInput On
            MouseMove, 400, 308, 0
            MouseClick, left
            Sleep, 500
            MouseClick, left
            Sleep, 5000
            MouseMove, 175, 125, 0
            MouseClick, left
            MouseClick, left
            Sleep, 500
            MouseClick, left
            MouseClick, left
            Sleep, 5000
            BlockInput Off
        }
    }
}