DC 插件：新增 <DC_AddComment> <DC_RemoveComment> <DC_EditComment>

DoubleCommander:
    global DC_Class := "TTOTAL_CMD"
    global DC := "ahk_class " . DC_Class
    global DC_Dir := "c:\mine\app\doublecmd"
    global DC_Path := DC_Dir . "\doublecmd.exe --no-splash"
    ; 用于记录文件打开对话框所属窗体
    global DC_CallerId := 0

    DC_Name := "DoubleCommander"

    Vim.SetWin(DC_Name, DC_Class, "doublecmd.exe")
    Vim.Mode("normal", DC_Name)

    Vim.BeforeActionDo("DC_ForceInsertMode", DC_Name)
return

DC_ForceInsertMode() {
    ControlGetFocus, Ctrl
    ; Edit 用于底部命令行
    ; Windows1 或 Windows3 用于磁盘列表
    ; Button 用于各种确认窗口，影响正常使用
    if (InStr(Ctrl, "Edit") || Ctrl == "Window1" || Ctrl == "Window3")  {
        return true
    }

    WinGet, MenuID, ID, AHK_CLASS #32768
    if (MenuID != "") {
        return true
    }

    return false
}

DC_Run(Cmd) {
    ControlSetText, Edit1, % Cmd, % DC
    ControlSend, Edit1, {Enter}, % DC
}

DC_RunGet(Cmd, SaveClipboard := True) {
    if (SaveClipboard) {
        ClipSaved := ClipboardAll
    }

    Clipboard := ""

    DC_Run(Cmd)

    ClipWait, 1

    if (SaveClipboard) {
        Result := Clipboard

        Clipboard := ClipSaved
        ClipSaved := ""

        return Result
    }

    return Clipboard
}

; 返回值 [1]: left/right [2]: 左侧面板所占比例 0-100
DC_GetPanelInfo() {
    return StrSplit(DC_RunGet("cm_CopyPanelInfoToClip"), " ")
}

DC_ExecuteToolbarItem(ID) {
    DC_Run("cm_ExecuteToolbarItem ToolItemID=" . ID)
}

DC_OpenPath(Path, InNewTab := true, LeftOrRight := "") {
    LeftOfRight := DC_GetPanelInfo()[1]
    if (LeftOfRight == "right") {
        LeftOrRight := "-R"
    } else {
        LeftOrRight := "-L"
    }

    if (InNewTab) {
        Run, %DC_Path% -C -T "%LeftOrRight%" "%Path%"
    } else {
        Run, %DC_Path% -C "%LeftOrRight%" "%Path%"
    }
}

; funcend

<DC_Test>:
    ; DC_ExecuteToolbarItem("{700FF494-B939-48A3-B248-8823EB366AEA}")
    DC_Run("cm_About")
return

<DC_Restart>:
    WinClose, % DC
    WinWaitClose, % DC, , 2

    Run, % DC_Path

    WinWaitActive, % DC

    if (!WinExist(DC)) {
        MsgBox, 重启失败 %ErrorMessage%
    }
return

<DC_Toggle_50_100>:
    PanelInfo := DC_GetPanelInfo()

    if (Abs(50 - PanelInfo[2]) < 10) {
        if (PanelInfo[1] == "left") {
            DC_Run("cm_PanelsSplitterPerPos splitpct=100")
        } else {
            DC_Run("cm_PanelsSplitterPerPos splitpct=0")
        }
    } else {
        DC_Run("cm_PanelsSplitterPerPos splitpct=50")
    }
return

<DC_PrevParallelDir>:
    SleepTime := 50

    OldPwd := DC_RunGet("cm_CopyCurrentPathToClip")

    if (StrLen(OldPwd) == 3) {
        ; 在根分区

        return
    }

    DC_Run("cm_ChangeDirToParent")
    Sleep, % SleepTime

    ; 可能没跳转过去 TODO
    DC_Run("cm_GoToPrevEntry")
    Sleep, % SleepTime

    DC_Run("cm_EnterActiveDir")
    Sleep, % SleepTime
return

<DC_NextParallelDir>:
    SleepTime := 50

    OldPwd := DC_RunGet("cm_CopyCurrentPathToClip")

    if (StrLen(OldPwd) == 3) {
        ; 在根分区

        return
    }

    DC_Run("cm_ChangeDirToParent")
    Sleep, % SleepTime

    ; 可能没跳转过去 TODO
    DC_Run("cm_GoToNextEntry")
    Sleep, % SleepTime

    DC_Run("cm_EnterActiveDir")
    Sleep, % SleepTime

    Pwd := DC_RunGet("cm_CopyCurrentPathToClip", false)
    Sleep, % SleepTime

    if (OldPwd != Pwd && InStr(OldPwd, Pwd) == 1) {
        ; 下一个是文件
        DC_Run("cm_ViewHistoryPrev")
    }
return

<DC_CreateNewFile>:
    ControlGetFocus, TLB, % DC
    ControlGetPos, Xn, Yn, , , % TLB, % DC

    Menu, NewFileMenu, Add
    Menu, NewFileMenu, DeleteAll
    Menu, NewFileMenu, Add , S >> 快捷方式, <DC_CreateFileShortcut>
    Menu, NewFileMenu, Icon, S >> 快捷方式, %A_WinDir%\system32\Shell32.dll, 264
    Menu, NewFileMenu, Add

    Loop, % DC_Dir . "\shellnew\*.*" {
        Ft := SubStr(A_LoopFileName, 1, 1) . " >> " . A_LoopFileName
        Menu, NewFileMenu, Add, % Ft, DC_NewFileMenuAction
        Menu, NewFileMenu, Icon, % Ft, %A_WinDir%\system32\Shell32.dll
    }

    Menu, NewFileMenu, Show, % Xn, % Yn + 2
return

DC_NewFileMenuAction:
    Filename := RegExReplace(A_ThisMenuItem, ".\s>>\s")
    FilePath := DC_Dir . "\ShellNew\" . Filename

    Gui, Destroy
    Gui, Add, Text, x12 y20 w50 h20 +Center, 模板源
    Gui, Add, Edit, x72 y20 w300 h20 Disabled, % FilePath
    Gui, Add, Text, x12 y50 w50 h20 +Center, 新建文件
    Gui, Add, Edit, x72 y50 w300 h20, % Filename
    Gui, Add, Button, x162 y80 w90 h30 gDC_NewFileOk default, 确认(&S)
    Gui, Add, Button, x282 y80 w90 h30 gDC_NewFileClose , 取消(&C)
    Gui, Show, w400 h120, 新建文件

    if (InStr(Filename, ".")) {
        ; 只选定扩展名之外的文件名
        PostMessage, 0x0B1, 0, % InStr(Filename, ".") - 1, Edit2, A
    }
return

DC_NewFileClose:
    Gui, Destroy
return

DC_NewFileOK:
    GuiControlGet, SrcFilePath, , Edit1
    GuiControlGet, NewFilename, , Edit2

    DstPath := DC_RunGet("cm_CopyCurrentPathToClip")

    if (InStr(DstPath, "`r")) {
        DstPath := SubStr(DstPath, 1, InStr(DstPath, "`r") - 1)
    } else if (DstPath == "") {
        return
    }

    NewFilePath := DstPath . NewFilename
    if (FileExist(NewFilePath)) {
        MsgBox, 4, 新建文件, 新建文件已存在，是否覆盖？
        IfMsgBox No
            return
    }

    FileCopy, % SrcFilePath, % NewFilePath, 1

    ; 虽然不是完全匹配，基本也能用了
    DC_Run("cm_QuickSearch text=" . NewFilename)

    Gui, Destroy
return

<DC_Toggle>:
    if (WinExist(DC)) {
        WinGet, Ac, MinMax, % DC
        if (Ac == -1) {
            WinActivate, % DC
        } else {
            if (!WinActive(DC)) {
                WinActivate, % DC
            } else {
                WinMinimize, % DC
            }
        }
    } else {
        Run, % DC_Path
        WinWait, % DC

        if (!WinActive(DC)) {
            WinActivate, % DC
        }
    }
return

<DC_MarkFile>:
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    Result := """" . StrReplace(SelectedFiles, "`r`n", """ 🖥`r`n""") . """ 🖥`r`n"

    Sleep, 10
    DC_Run("cm_MarkUnmarkAll")

    FileAppend, % Result, % DC_RunGet("cm_CopyCurrentPathToClip") . "descript.ion", UTF-8-RAW

    DC_Run("cm_Refresh")

    SelectedFiles := ""
    Result := ""
return

<DC_UnMarkFile>:
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    DescriptPath := DC_RunGet("cm_CopyCurrentPathToClip") . "descript.ion"

    ; 有时取消选定会失效，改 20 也一样，不清楚怎么修复
    Sleep, 10
    DC_Run("cm_MarkUnmarkAll")

    FileRead, Content, % DescriptPath

    Loop, Parse, SelectedFiles, `n, `r
    {
        Content := StrReplace(Content, """" . A_LoopField . """ 🖥`r`n")
    }

    FileDelete, % DescriptPath

    if (Content != "") {
        FileAppend, % Content, % DescriptPath, UTF-8-RAW
    }

    DC_Run("cm_Refresh")

    SelectedFiles := ""
    Content := ""
return

<DC_AddComment>:
    InputBox, Content, , 请输入注释, , 375, 125
    if ErrorLevel
        return

    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")

    Result := """" . StrReplace(SelectedFiles, "`r`n", """ " . Content . "`r`n""") . """ " . Content . "`r`n"

    Sleep, 10
    DC_Run("cm_MarkUnmarkAll")

    FileAppend, % Result, % DC_RunGet("cm_CopyCurrentPathToClip") . "descript.ion", UTF-8-RAW

    DC_Run("cm_Refresh")

    SelectedFiles := ""
    Result := ""
return

<DC_RemoveComment>:
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    DescriptPath := DC_RunGet("cm_CopyCurrentPathToClip") . "descript.ion"

    ; 有时取消选定会失效，改 20 也一样，不清楚怎么修复
    Sleep, 10
    DC_Run("cm_MarkUnmarkAll")

    FileRead, Content, % DescriptPath

    Loop, Parse, SelectedFiles, `n, `r
    {
        Content := RegexReplace(Content, "m)^""?" . A_LoopField . """? .*")
    }

    ; \K：前边的不算，重新开始匹配
    Content := RegexReplace(Content, "(^|\R)\K\R+")

    FileDelete, % DescriptPath

    if (Content != "") {
        FileAppend, % Content, % DescriptPath, UTF-8-RAW
    }

    DC_Run("cm_Refresh")

    SelectedFiles := ""
    Content := ""
return

<DC_EditComment>:
    Run, % editor . " """ . DC_RunGet("cm_CopyCurrentPathToClip") . "descript.ion"""
return

<DC_ToggleShowInfo>:
    Vim.GetWin(DC_Name).SetInfo(!Vim.GetWin(DC_Name).info)
return

<DC_CopyFileContent>:
    Fileread, Contents, % DC_RunGet("cm_CopyFullNamesToClip", false)
    Clipboard := Contents
return

<DC_CopyFilenamesOnly>:
    Result := DC_RunGet("cm_CopyFullNamesToClip")

    SplitPath, Result, OutFileName, , , OutFilenameNoExt

    if (InStr(FileExist(Result), "D")) {
        Clipboard := OutFileName
    } else if (InStr(Result, ".")) {
        Clipboard := OutFilenameNoExt
    }
return

<DC_CreateFileShortcut>:
    FilePath := DC_RunGet("cm_CopyFullNamesToClip")

    OutVar := FileExist(FilePath)
    if (InStr(OutVar, "D")) {
        FileCreateShortcut, % FilePath, % FilePath . ".lnk", % RegExReplace(FilePath, "\\[^\\]*$")
    } else if (OutVar != "") {
        FileCreateShortcut, % FilePath, % RegExReplace(FilePath, "\.[^.]*$", ".lnk"), % RegExReplace(FilePath, "\\[^\\]*$")
    }
return

<DC_Focus>:
    IfWinExist, % DC
        Winactivate, % DC
    else {
        Run, % DC_Path
        WinWait, % DC
        IfWinNotActive, % DC
            WinActivate, % DC
    }
return

<DC_MapKeys>:
	Vim.Mode("normal", DC_Name)
    Vim.Map("<S-Enter>", "<DC_SelectedCurrentDir>", DC_Name)
    Vim.Map("<Esc>", "<DC_ReturnToCaller>", DC_Name)
return

<DC_UnMapKeys>:
	Vim.Mode("normal", DC_Name)
    Vim.Map("<S-Enter>", "<Default>", DC_Name)
    Vim.Map("<Esc>", "<Default>", DC_Name)
return

; 返回调用者
<DC_ReturnToCaller>:
    gosub <DC_UnMapKeys>

    WinActivate, ahk_id %DC_CallerId%

    DC_CallerId := 0
return

; 非 TC 窗口按下后激活 TC 窗口
; TC 窗口按下后复制当前选中文件返回原窗口后粘贴
<DC_OpenDCDialog>:
    WinGetClass, Name, A

    ; 在 DC 按下快捷键时，激活调用窗体并执行粘贴操作
    if (Name == DC_Class) {
        if (DC_CallerId != 0) {
            gosub <DC_Selected>
            return
		}
    } else {
        DC_CallerId := WinExist("A")
        if (DC_CallerId == 0) {
            return
		}

        gosub <DC_Focus>
        gosub <DC_MapKeys>
    }
return

<DC_Selected>:
    gosub <DC_UnMapKeys>

    if (DC_CallerId == 0) {
        return
    }

    ; 避免发送回车时受同时按下的 Win 等键影响
    ; MsgBox, , , 处理中, 0.3
    ; 通过修改 DC 代码解决

    Pwd := DC_RunGet("cm_CopyCurrentPathToClip", false)

    Filename := DC_RunGet("cm_CopyNamesToClip", false)

    WinActivate, ahk_id %DC_CallerId%
    WinWait, ahk_id %DC_CallerId%
    DC_CallerId := 0

    if (!InStr(Filename, "`n")) {
        Clipboard := Pwd . Filename
        Send, {Home}
        Send, ^v
        Send, {Enter}

        return
    }

    ; 多选

    Files := ""
    Loop, Parse, FIlename, `n, `r
        Files .= """" . A_LoopField  . """ "

    ; 第一步：跳转到当前路径
    Clipboard := Pwd
    Send, ^a
    Send, ^v
    Send, {Enter}
    sleep, 100

    ; 第二步：提交文件名
    Clipboard := Files
    Send, ^v
    Send, {Enter}
return

<DC_SelectedCurrentDir>:
    gosub <DC_UnMapKeys>

    if (DC_CallerId == 0) {
        return
    }

    DC_Run("cm_CopyCurrentPathToClip")

    WinActivate, ahk_id %DC_CallerId%
    WinWait, ahk_id %DC_CallerId%
    DC_CallerId := 0

    Send, {Home}
    Send, ^v
    Send, {Enter}
return

DoubleCommander:
    global DC_Class := "TTOTAL_CMD"
    global DC := "ahk_class " . DC_Class
    global DC_Dir := "c:\mine\app\doublecmd"
    global DC_Path := DC_Dir . "\doublecmd.exe --no-splash"
    ; 用于记录文件打开对话框所属窗体
    global DC_CallerId := 0

    DC_Name := "DoubleCommander"

    Vim.SetWin(DC_Name, DC_Class, "doublecmd.exe")
    Vim.Mode("normal", DC_Name)

    Vim.BeforeActionDo("DC_ForceInsertMode", DC_Name)
return

DC_ForceInsertMode() {
    ControlGetFocus, Ctrl
    ; Edit 用于底部命令行
    ; Windows1 或 Windows3 用于磁盘列表
    ; Button 用于各种确认窗口，影响正常使用
    if (InStr(Ctrl, "Edit") || Ctrl == "Window1" || Ctrl == "Window3")  {
        return true
    }

    WinGet, MenuID, ID, AHK_CLASS #32768
    if (MenuID != "") {
        return true
    }

    return false
}

DC_Run(Cmd) {
    ControlSetText, Edit1, % Cmd, % DC
    ControlSend, Edit1, {Enter}, % DC
}

DC_RunGet(Cmd, SaveClipboard := True) {
    if (SaveClipboard) {
        ClipSaved := ClipboardAll
    }

    Clipboard := ""

    DC_Run(Cmd)

    ClipWait, 1

    if (SaveClipboard) {
        Result := Clipboard

        Clipboard := ClipSaved
        ClipSaved := ""

        return Result
    }

    return Clipboard
}

; 返回值 [1]: left/right [2]: 左侧面板所占比例 0-100
DC_GetPanelInfo() {
    return StrSplit(DC_RunGet("cm_CopyPanelInfoToClip"), " ")
}

DC_ExecuteToolbarItem(ID) {
    DC_Run("cm_ExecuteToolbarItem ToolItemID=" . ID)
}

DC_OpenPath(Path, InNewTab := true, LeftOrRight := "") {
    LeftOfRight := DC_GetPanelInfo()[1]
    if (LeftOfRight == "right") {
        LeftOrRight := "-R"
    } else {
        LeftOrRight := "-L"
    }

    if (InNewTab) {
        Run, %DC_Path% -C -T "%LeftOrRight%" "%Path%"
    } else {
        Run, %DC_Path% -C "%LeftOrRight%" "%Path%"
    }
}

; funcend

<DC_Test>:
    ; DC_ExecuteToolbarItem("{700FF494-B939-48A3-B248-8823EB366AEA}")
    DC_Run("cm_About")
return

<DC_Restart>:
    WinClose, % DC
    WinWaitClose, % DC, , 2

    Run, % DC_Path

    WinWaitActive, % DC

    if (!WinExist(DC)) {
        MsgBox, 重启失败 %ErrorMessage%
    }
return

<DC_Toggle_50_100>:
    PanelInfo := DC_GetPanelInfo()

    if (Abs(50 - PanelInfo[2]) < 10) {
        if (PanelInfo[1] == "left") {
            DC_Run("cm_PanelsSplitterPerPos splitpct=100")
        } else {
            DC_Run("cm_PanelsSplitterPerPos splitpct=0")
        }
    } else {
        DC_Run("cm_PanelsSplitterPerPos splitpct=50")
    }
return

<DC_PrevParallelDir>:
    SleepTime := 50

    OldPwd := DC_RunGet("cm_CopyCurrentPathToClip")

    if (StrLen(OldPwd) == 3) {
        ; 在根分区

        return
    }

    DC_Run("cm_ChangeDirToParent")
    Sleep, % SleepTime

    ; 可能没跳转过去 TODO
    DC_Run("cm_GoToPrevEntry")
    Sleep, % SleepTime

    DC_Run("cm_EnterActiveDir")
    Sleep, % SleepTime
return

<DC_NextParallelDir>:
    SleepTime := 50

    OldPwd := DC_RunGet("cm_CopyCurrentPathToClip")

    if (StrLen(OldPwd) == 3) {
        ; 在根分区

        return
    }

    DC_Run("cm_ChangeDirToParent")
    Sleep, % SleepTime

    ; 可能没跳转过去 TODO
    DC_Run("cm_GoToNextEntry")
    Sleep, % SleepTime

    DC_Run("cm_EnterActiveDir")
    Sleep, % SleepTime

    Pwd := DC_RunGet("cm_CopyCurrentPathToClip", false)
    Sleep, % SleepTime

    if (OldPwd != Pwd && InStr(OldPwd, Pwd) == 1) {
        ; 下一个是文件
        DC_Run("cm_ViewHistoryPrev")
    }
return

<DC_CreateNewFile>:
    ControlGetFocus, TLB, % DC
    ControlGetPos, Xn, Yn, , , % TLB, % DC

    Menu, NewFileMenu, Add
    Menu, NewFileMenu, DeleteAll
    Menu, NewFileMenu, Add , S >> 快捷方式, <DC_CreateFileShortcut>
    Menu, NewFileMenu, Icon, S >> 快捷方式, %A_WinDir%\system32\Shell32.dll, 264
    Menu, NewFileMenu, Add

    Loop, % DC_Dir . "\shellnew\*.*" {
        Ft := SubStr(A_LoopFileName, 1, 1) . " >> " . A_LoopFileName
        Menu, NewFileMenu, Add, % Ft, DC_NewFileMenuAction
        Menu, NewFileMenu, Icon, % Ft, %A_WinDir%\system32\Shell32.dll
    }

    Menu, NewFileMenu, Show, % Xn, % Yn + 2
return

DC_NewFileMenuAction:
    Filename := RegExReplace(A_ThisMenuItem, ".\s>>\s")
    FilePath := DC_Dir . "\ShellNew\" . Filename

    Gui, Destroy
    Gui, Add, Text, x12 y20 w50 h20 +Center, 模板源
    Gui, Add, Edit, x72 y20 w300 h20 Disabled, % FilePath
    Gui, Add, Text, x12 y50 w50 h20 +Center, 新建文件
    Gui, Add, Edit, x72 y50 w300 h20, % Filename
    Gui, Add, Button, x162 y80 w90 h30 gDC_NewFileOk default, 确认(&S)
    Gui, Add, Button, x282 y80 w90 h30 gDC_NewFileClose , 取消(&C)
    Gui, Show, w400 h120, 新建文件

    if (InStr(Filename, ".")) {
        ; 只选定扩展名之外的文件名
        PostMessage, 0x0B1, 0, % InStr(Filename, ".") - 1, Edit2, A
    }
return

DC_NewFileClose:
    Gui, Destroy
return

DC_NewFileOK:
    GuiControlGet, SrcFilePath, , Edit1
    GuiControlGet, NewFilename, , Edit2

    DstPath := DC_RunGet("cm_CopyCurrentPathToClip")

    if (InStr(DstPath, "`r")) {
        DstPath := SubStr(DstPath, 1, InStr(DstPath, "`r") - 1)
    } else if (DstPath == "") {
        return
    }

    NewFilePath := DstPath . NewFilename
    if (FileExist(NewFilePath)) {
        MsgBox, 4, 新建文件, 新建文件已存在，是否覆盖？
        IfMsgBox No
            return
    }

    FileCopy, % SrcFilePath, % NewFilePath, 1

    ; 虽然不是完全匹配，基本也能用了
    DC_Run("cm_QuickSearch text=" . NewFilename)

    Gui, Destroy
return

<DC_Toggle>:
    if (WinExist(DC)) {
        WinGet, Ac, MinMax, % DC
        if (Ac == -1) {
            WinActivate, % DC
        } else {
            if (!WinActive(DC)) {
                WinActivate, % DC
            } else {
                WinMinimize, % DC
            }
        }
    } else {
        Run, % DC_Path
        WinWait, % DC

        if (!WinActive(DC)) {
            WinActivate, % DC
        }
    }
return

<DC_MarkFileSingle>:
    DC_Run("cm_EditComment")
    ; 不要在已有备注的文件使用
    Send, ^+{End}🖥{F2}
return

<DC_UnMarkFileSingle>:
    DC_Run("cm_EditComment")
    ; 删除 DC_MarkFile 的文件标记，也可用于清空文件备注
    Send, ^+{End}{Del}{F2}
return

<DC_MarkFile>:
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    Result := """" . StrReplace(SelectedFiles, "`r`n", """ 🖥`r`n""") . """ 🖥`r`n"

    Sleep, 10
    DC_Run("cm_MarkUnmarkAll")

    FileAppend, % Result, % DC_RunGet("cm_CopyCurrentPathToClip") . "\descript.ion", UTF-8-RAW

    DC_Run("cm_Refresh")

    SelectedFiles := ""
    Result := ""
return

<DC_UnMarkFile>:
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    DescriptPath := DC_RunGet("cm_CopyCurrentPathToClip") . "\descript.ion"

    ; 有时取消选定会失效，改 20 也一样，不清楚怎么修复
    Sleep, 10
    DC_Run("cm_MarkUnmarkAll")

    FileRead, Content, % DescriptPath

    Loop, Parse, SelectedFiles, `r`n
    {
        Content := StrReplace(Content, """" . A_LoopField . """ 🖥`r`n")
    }

    FileDelete, % DescriptPath

    if (Content != "") {
        FileAppend, % Content, % DescriptPath, UTF-8-RAW
    }

    DC_Run("cm_Refresh")

    SelectedFiles := ""
    Content := ""
return

<DC_ToggleShowInfo>:
    Vim.GetWin(DC_Name).SetInfo(!Vim.GetWin(DC_Name).info)
return

<DC_CopyFileContent>:
    Fileread, Contents, % DC_RunGet("cm_CopyFullNamesToClip", false)
    Clipboard := Contents
return

<DC_CopyFilenamesOnly>:
    Result := DC_RunGet("cm_CopyFullNamesToClip")

    SplitPath, Result, OutFileName, , , OutFilenameNoExt

    if (InStr(FileExist(Result), "D")) {
        Clipboard := OutFileName
    } else if (InStr(Result, ".")) {
        Clipboard := OutFilenameNoExt
    }
return

<DC_CreateFileShortcut>:
    FilePath := DC_RunGet("cm_CopyFullNamesToClip")

    OutVar := FileExist(FilePath)
    if (InStr(OutVar, "D")) {
        FileCreateShortcut, % FilePath, % FilePath . ".lnk", % RegExReplace(FilePath, "\\[^\\]*$")
    } else if (OutVar != "") {
        FileCreateShortcut, % FilePath, % RegExReplace(FilePath, "\.[^.]*$", ".lnk"), % RegExReplace(FilePath, "\\[^\\]*$")
    }
return

<DC_Focus>:
    IfWinExist, % DC
        Winactivate, % DC
    else {
        Run, % DC_Path
        WinWait, % DC
        IfWinNotActive, % DC
            WinActivate, % DC
    }
return

<DC_MapKeys>:
	Vim.Mode("normal", DC_Name)
    Vim.Map("<S-Enter>", "<DC_SelectedCurrentDir>", DC_Name)
    Vim.Map("<Esc>", "<DC_ReturnToCaller>", DC_Name)
return

<DC_UnMapKeys>:
	Vim.Mode("normal", DC_Name)
    Vim.Map("<S-Enter>", "<Default>", DC_Name)
    Vim.Map("<Esc>", "<Default>", DC_Name)
return

; 返回调用者
<DC_ReturnToCaller>:
    gosub <DC_UnMapKeys>

    WinActivate, ahk_id %DC_CallerId%

    DC_CallerId := 0
return

; 非 TC 窗口按下后激活 TC 窗口
; TC 窗口按下后复制当前选中文件返回原窗口后粘贴
<DC_OpenDCDialog>:
    WinGetClass, Name, A

    ; 在 DC 按下快捷键时，激活调用窗体并执行粘贴操作
    if (Name == DC_Class) {
        if (DC_CallerId != 0) {
            gosub <DC_Selected>
            return
		}
    } else {
        DC_CallerId := WinExist("A")
        if (DC_CallerId == 0) {
            return
		}

        gosub <DC_Focus>
        gosub <DC_MapKeys>
    }
return

<DC_Selected>:
    gosub <DC_UnMapKeys>

    if (DC_CallerId == 0) {
        return
    }

    ; 避免发送回车时受同时按下的 Win 等键影响
    ; MsgBox, , , 处理中, 0.3
    ; 通过修改 DC 代码解决

    Pwd := DC_RunGet("cm_CopyCurrentPathToClip", false)

    Filename := DC_RunGet("cm_CopyNamesToClip", false)

    WinActivate, ahk_id %DC_CallerId%
    WinWait, ahk_id %DC_CallerId%
    DC_CallerId := 0

    if (!InStr(Filename, "`n")) {
        Clipboard := Pwd . Filename
        Send, {Home}
        Send, ^v
        Send, {Enter}

        return
    }

    ; 多选

    Files := ""
    Loop, Parse, FIlename, `n, `r
        Files .= """" . A_LoopField  . """ "

    ; 第一步：跳转到当前路径
    Clipboard := Pwd
    Send, ^a
    Send, ^v
    Send, {Enter}
    sleep, 100

    ; 第二步：提交文件名
    Clipboard := Files
    Send, ^v
    Send, {Enter}
return

<DC_SelectedCurrentDir>:
    gosub <DC_UnMapKeys>

    if (DC_CallerId == 0) {
        return
    }

    DC_Run("cm_CopyCurrentPathToClip")

    WinActivate, ahk_id %DC_CallerId%
    WinWait, ahk_id %DC_CallerId%
    DC_CallerId := 0

    Send, {Home}
    Send, ^v
    Send, {Enter}
return


no message

no message

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;~ please use this ! as first line in every script before all includes! :)
isDevellopperMode=true ; enthllt auch update script.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#Include init_global.init.inc.ahk

#Persistent
#SingleInstance,force

;~ SetTimer,reloadLabel,120000

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; if you press  letter or curser move script will open help file and get cursor back
; F1 will be triggerd as soon something is typed and idle time is more then 650 or so
; helpful during screencast or if you often use helpfile
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

doMoveCursor:=false
typedGlobal:=""

setbatchlines -1
SetTitleMatchMode,2

is_set_AutoHotkeyHelp_AlwaysOnTop := false
Loop,
{
  is_set_AutoHotkeyHelp_AlwaysOnTop := set_AutoHotkeyHelp_AlwaysOnTop(is_set_AutoHotkeyHelp_AlwaysOnTop)

  WinGetActiveTitle,at
  WinGetClass,ac,%at%
  atc := at . " ahk_class " . ac
  ;~ ToolTip,%A_TimeIdle% := A_TimeIdle `n
  ;~ ToolTip,%typedGlobal%
  ;~ if(  InStr(atc,"ahk_class SciTEWindow") && A_TimeIdle > 650  ){
  if(  InStr(atc,"ahk_class SciTEWindow") && A_TimeIdle > 4000  ){
    ;~ p := getMousePos()

    ;~ if ( p["x"] != pB["x"r] or  p["y"] != pB["y"]  ){
      ; mouse move recognition
      ;~ pB := p
      ;~ Sleep,700

      ;~ continue
    ;~ }
    if(StrLen(typedGlobal)<1)
      continue

    typedGlobal:=""

				;~ ToolTip % rArea["l"] . " " rArea["t"] . " `n " rArea["r"] . " " rArea["b"] . "  `n  `n " p["x"] . " " p["y"] . " "

    if(doMoveCursor==true){
      SetKeyDelay,0,0
      Send,{Left 3}
    }
    SetKeyDelay,0,30
    Send,{f1}
    ;~ ToolTip,f1 58
    Sleep,10
    ; fight focus back
  ;~ rightNum:=3

  loop
  {
    WinActivate,%at%
    IfWinActive,%at%
    {
      if(doMoveCursor==true){
        SetKeyDelay,0,0
        Send,{Right 3}
      }
      goto, break_outer32
    }
    Sleep,10
  }

break_outer32:

  fightFocusBack(at)
  Sleep,500
 }
}
; hjkl
return

letterPressed(l,typedGlobal){
  ;~ global typedGlobal
  typedGlobal .= l ;
  ;~ If(l = " "){
    ;~ openHelpFile(typedGlobal)
    ;~ typedGlobal:=""
  ;~ }
  return typedGlobal
}

#IfWinActive, ahk_class SciTEWindow
  SciTEWin := "ahk_class SciTEWindow"

~LButton::
return
      WinGetActiveTitle,at
  WinGetClass,ac,%at%
  atc := at . " ahk_class " . ac

    Send,{Blind}
    Sleep,100
    ;~ SetKeyDelay,delay,pressduration
    SetKeyDelay,40,40
    ;~ Suspend,ontestTestTest.
    Suspend,on
    IfWinActive,%SciTEWin%
      Send,{f1}
        ToolTip,f1 114

    ;~ SendInput,{f1}
    Suspend,off
    ;~ SendPlay,{f1}
    ;~ Send,{f1}

    ;~ Send,{Left}{Right} ; that shoud trigger F1 - its workaround
    ;~ Suspend,off

    SetKeyDelay,-1,-1
    ;~ Last_A_This:=A_ThisFunc . A_ThisLabel
    ;~ ToolTip1sec(A_LineNumber . " " . A_ScriptName . " " . Last_A_This)

    fightFocusBack(at)
return

;~ fightFocusBack(at)

fightFocusBack(at){
WinWaitNotActive,%at%,,2
  lll(A_LineNumber, "liveHelpFileView.v1.2.ahk",Last_A_This)
  Loop
  {
    IfWinNotExist,%at%
      return
      IfWinNotActive,%at%
        WinActivate,%at%
      ;~ WinWaitActive,%at%,,1
      ;~ IfWinActive,%at%
      ;~ {
        ;~ Goto, break_outer40
        ;~ ToolTip,fight for focus
        ;~ lll(A_LineNumber, "liveHelpFileView.v1.2.ahk",Last_A_This)
      ;~ }
      Sleep,40
      ;AutoHotkey Help ahk_class HH Parent
 ; w=1280,
 ; x=428,y=28,t=0x241932
      IfWinActive,%at%
      {
        Send,{Esc} ; if text search is open it jumps to text search. ugly. 15-06-14_22-46
        goto,break_outer40
      }
    }
    break_outer40:
    lll(A_LineNumber, "liveHelpFileView.v1.2.ahk",Last_A_This)
    Sleep,700
  }

if(true){

#IfWinActive,ahk_class SciTEWindow  ; x=588,y=22,t=0xf19d8
~*a::typedGlobal := letterPressed("a",typedGlobal)
~*b::typedGlobal := letterPressed("b",typedGlobal)
~*c::typedGlobal := letterPressed("c",typedGlobal)
~*d::typedGlobal := letterPressed("d",typedGlobal)
~*e::typedGlobal := letterPressed("e",typedGlobal)
~*f::typedGlobal := letterPressed("f",typedGlobal)
~*g::typedGlobal := letterPressed("g",typedGlobal)
~*h::typedGlobal := letterPressed("h",typedGlobal)
~*i::typedGlobal := letterPressed("i",typedGlobal)
~*j::typedGlobal := letterPressed("j",typedGlobal)
~*k::typedGlobal := letterPressed("k",typedGlobal)
~*l::typedGlobal := letterPressed("l",typedGlobal)
~*m::typedGlobal := letterPressed("m",typedGlobal)
~*n::typedGlobal := letterPressed("n",typedGlobal)
~*o::typedGlobal := letterPressed("o",typedGlobal)
~*p::typedGlobal := letterPressed("p",typedGlobal)
~*q::typedGlobal := letterPressed("q",typedGlobal)
~*r::typedGlobal := letterPressed("r",typedGlobal)
~*s::typedGlobal := letterPressed("s",typedGlobal)
~*t::typedGlobal := letterPressed("t",typedGlobal)
~*u::typedGlobal := letterPressed("u",typedGlobal)
~*v::typedGlobal := letterPressed("v",typedGlobal)
~*w::typedGlobal := letterPressed("w",typedGlobal)
~*x::typedGlobal := letterPressed("x",typedGlobal)
~*y::typedGlobal := letterPressed("y",typedGlobal)
~*z::typedGlobal := letterPressed("z",typedGlobal)
~Space::typedGlobal := letterPressed(" ",typedGlobal)
;~ ~*::typedGlobal := letterPressed("",typedGlobal)
;~ ~*::typedGlobal := letterPressed("",typedGlobal)
;~ ~*::typedGlobal := letterPressed("",typedGlobal)
~*Left::typedGlobal := letterPressed("Left",typedGlobal)
~*Right::typedGlobal := letterPressed("Right",typedGlobal)
~*Up::typedGlobal := letterPressed("Up",typedGlobal)
~*Down::typedGlobal := letterPressed("Down",typedGlobal)
;~ ~*Click::typedGlobal := letterPressed("Click",typedGlobal)
}

set_AutoHotkeyHelp_AlwaysOnTop(isOnTop){
  if(isOnTop==true)
    return isOnTop
  autoHotkey_Help_ahk = AutoHotkey Help ahk_class HH Parent
  ;~ autoHotkey_Help_ahk := AutoHotkey Help
    IfWinNotExist,%autoHotkey_Help_ahk%
    {
      ;~ MsgBox, :( %autoHotkey_Help_ahk%
      return false
    }
    WinSet, AlwaysOnTop, On,%autoHotkey_Help_ahk%
    ;~ isOnTop:=true
    return true

}

reloadLabel:
; buggy if not reloadet after a while. its workAround. 15-06-12_11-01 :)
Reload
return

#Include functions.inc.ahk
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;~ subroutinen beispielsweise msen ans Dateiende
#Include functions_dateiende.inc.ahk
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;~ please use this ! as first line in every script before all includes! :)
isDevellopperMode=true ; enthllt auch update script.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#Include init_global.init.inc.ahk

#Persistent

SetTimer,reloadLabel,120000

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; if you press  letter or curser move script will open help file and get cursor back
; F1 will be triggerd as soon something is typed and idle time is more then 650 or so
; helpful during screencast or if you often use helpfile
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

doMoveCursor:=false
typedGlobal:=""

setbatchlines -1
SetTitleMatchMode,2

is_set_AutoHotkeyHelp_AlwaysOnTop := false
Loop,
{
  is_set_AutoHotkeyHelp_AlwaysOnTop := set_AutoHotkeyHelp_AlwaysOnTop(is_set_AutoHotkeyHelp_AlwaysOnTop)

  WinGetActiveTitle,at
  WinGetClass,ac,%at%
  atc := at . " ahk_class " . ac
  ;~ ToolTip,%A_TimeIdle% := A_TimeIdle `n
  ;~ ToolTip,%typedGlobal%
  ;~ if(  InStr(atc,"ahk_class SciTEWindow") && A_TimeIdle > 650  ){
  if(  InStr(atc,"ahk_class SciTEWindow") && A_TimeIdle > 4000  ){
    ;~ p := getMousePos()

    ;~ if ( p["x"] != pB["x"r] or  p["y"] != pB["y"]  ){
      ; mouse move recognition
      ;~ pB := p
      ;~ Sleep,700

      ;~ continue
    ;~ }
    if(StrLen(typedGlobal)<1)
      continue

    typedGlobal:=""

				;~ ToolTip % rArea["l"] . " " rArea["t"] . " `n " rArea["r"] . " " rArea["b"] . "  `n  `n " p["x"] . " " p["y"] . " "

    if(doMoveCursor==true){
      SetKeyDelay,0,0
      Send,{Left 3}
    }
    SetKeyDelay,0,30
    Send,{f1}
    Sleep,10
    ; fight focus back
  ;~ rightNum:=3

  loop
  {
    WinActivate,%at%
    IfWinActive,%at%
    {
      if(doMoveCursor==true){
        SetKeyDelay,0,0
        Send,{Right 3}
      }
      goto, break_outer32
    }
    Sleep,10
  }

break_outer32:

  fightFocusBack(at)
  Sleep,500
 }
}
; hjkl
return

letterPressed(l,typedGlobal){
  ;~ global typedGlobal
  typedGlobal .= l ;
  ;~ If(l = " "){
    ;~ openHelpFile(typedGlobal)
    ;~ typedGlobal:=""
  ;~ }
  return typedGlobal
}

#IfWinActive, ahk_class SciTEWindow
  SciTEWin := "ahk_class SciTEWindow"

~LButton::
      WinGetActiveTitle,at
  WinGetClass,ac,%at%
  atc := at . " ahk_class " . ac

    Send,{Blind}
    Sleep,100
    ;~ SetKeyDelay,delay,pressduration
    SetKeyDelay,40,40
    ;~ Suspend,ontestTestTest.
    Suspend,on
    IfWinActive,%SciTEWin%
      Send,{f1}
    ;~ SendInput,{f1}
    Suspend,off
    ;~ SendPlay,{f1}
    ;~ Send,{f1}

    ;~ Send,{Left}{Right} ; that shoud trigger F1 - its workaround
    ;~ Suspend,off

    SetKeyDelay,-1,-1
    ;~ Last_A_This:=A_ThisFunc . A_ThisLabel
    ;~ ToolTip1sec(A_LineNumber . " " . A_ScriptName . " " . Last_A_This)

    fightFocusBack(at)
return

;~ fightFocusBack(at)

fightFocusBack(at){
WinWaitNotActive,%at%,,2
  lll(A_LineNumber, "liveHelpFileView.v1.2.ahk",Last_A_This)
  Loop
  {
    IfWinNotExist,%at%
      return
      IfWinNotActive,%at%
        WinActivate,%at%
      ;~ WinWaitActive,%at%,,1
      ;~ IfWinActive,%at%
      ;~ {
        ;~ Goto, break_outer40
        ;~ ToolTip,fight for focus
        ;~ lll(A_LineNumber, "liveHelpFileView.v1.2.ahk",Last_A_This)
      ;~ }
      Sleep,40
      ;AutoHotkey Help ahk_class HH Parent
 ; w=1280,
 ; x=428,y=28,t=0x241932
      IfWinActive,%at%
      {
        Send,{Esc} ; if text search is open it jumps to text search. ugly. 15-06-14_22-46
        goto,break_outer40
      }
    }
    break_outer40:
    lll(A_LineNumber, "liveHelpFileView.v1.2.ahk",Last_A_This)
    Sleep,700
  }

if(true){

#IfWinActive,ahk_class SciTEWindow  ; x=588,y=22,t=0xf19d8
~*a::typedGlobal := letterPressed("a",typedGlobal)
~*b::typedGlobal := letterPressed("b",typedGlobal)
~*c::typedGlobal := letterPressed("c",typedGlobal)
~*d::typedGlobal := letterPressed("d",typedGlobal)
~*e::typedGlobal := letterPressed("e",typedGlobal)
~*f::typedGlobal := letterPressed("f",typedGlobal)
~*g::typedGlobal := letterPressed("g",typedGlobal)
~*h::typedGlobal := letterPressed("h",typedGlobal)
~*i::typedGlobal := letterPressed("i",typedGlobal)
~*j::typedGlobal := letterPressed("j",typedGlobal)
~*k::typedGlobal := letterPressed("k",typedGlobal)
~*l::typedGlobal := letterPressed("l",typedGlobal)
~*m::typedGlobal := letterPressed("m",typedGlobal)
~*n::typedGlobal := letterPressed("n",typedGlobal)
~*o::typedGlobal := letterPressed("o",typedGlobal)
~*p::typedGlobal := letterPressed("p",typedGlobal)
~*q::typedGlobal := letterPressed("q",typedGlobal)
~*r::typedGlobal := letterPressed("r",typedGlobal)
~*s::typedGlobal := letterPressed("s",typedGlobal)
~*t::typedGlobal := letterPressed("t",typedGlobal)
~*u::typedGlobal := letterPressed("u",typedGlobal)
~*v::typedGlobal := letterPressed("v",typedGlobal)
~*w::typedGlobal := letterPressed("w",typedGlobal)
~*x::typedGlobal := letterPressed("x",typedGlobal)
~*y::typedGlobal := letterPressed("y",typedGlobal)
~*z::typedGlobal := letterPressed("z",typedGlobal)
~Space::typedGlobal := letterPressed(" ",typedGlobal)
;~ ~*::typedGlobal := letterPressed("",typedGlobal)
;~ ~*::typedGlobal := letterPressed("",typedGlobal)
;~ ~*::typedGlobal := letterPressed("",typedGlobal)
~*Left::typedGlobal := letterPressed("Left",typedGlobal)
~*Right::typedGlobal := letterPressed("Right",typedGlobal)
~*Up::typedGlobal := letterPressed("Up",typedGlobal)
~*Down::typedGlobal := letterPressed("Down",typedGlobal)
}

set_AutoHotkeyHelp_AlwaysOnTop(isOnTop){
  if(isOnTop==true)
    return isOnTop
  autoHotkey_Help_ahk = AutoHotkey Help ahk_class HH Parent
  ;~ autoHotkey_Help_ahk := AutoHotkey Help
    IfWinNotExist,%autoHotkey_Help_ahk%
    {
      ;~ MsgBox, :( %autoHotkey_Help_ahk%
      return false
    }
    WinSet, AlwaysOnTop, On,%autoHotkey_Help_ahk%
    ;~ isOnTop:=true
    return true

}

reloadLabel:
; buggy if not reloadet after a while. its workAround. 15-06-12_11-01 :)
Reload
return

#Include functions.inc.ahk
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;~ subroutinen beispielsweise msen ans Dateiende
#Include functions_dateiende.inc.ahk
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


extend recently added test case

extend recently added test case

; truth values:
; ==========================================================
Assert(""    ? false : true, "Empty string is true")
Assert(0     ? false : true, "0 is true")
Assert(0.0   ? false : true, "0.0 is true")
Assert(false ? false : true, "false is true")
Assert(null  ? false : true, "null is true")
Assert(a     ? false : true, "Uninitialized var is not false")

Assert("a", "Non-empty string is false")
Assert(1, "1 is false")
Assert(true, "true is false")
Assert(!false, "!false is false")
; ==========================================================

Assert(0x2 "" == "2", "Hex-Int to string conversion failed")

five() {
	return(5)
}

Assert(five() "" == "5", "Return value failed")
Assert(5 ** 2 == 25.0, "Power failed")

cond() {
	if (true) {
		return(true)
	}
}
Assert(cond(), "function return in if failed")

glob := "var"
local_func() {
	Assert(local == null, "Uninit var in func was not null")
	if (true) {
		Assert(local == null, "Uninit var in if in func was not null")
	}

	local := true
	Assert(local, "Initialized local var in func failed")
	if (true) {
		Assert(local, "Initialized local var in if in func failed")
	}

	Assert(glob == null, "Global var was visible in function")
	if (true) {
		Assert(glob == null, "Global var was visible in if in function")
	}
}
local_func()

c := 5
c += 8.2
Assert(c == 13.2, "+= failed")

; just testing if the expression isn't too long
b := 5
b .= ": " 5 + 8.2 " = " c " = " . 13.2 " != " 1 * 1 - 13.2 + 5.8 " + 4e-2 == " 0.001 * (0 + 1) * 10 ** 0 " += c"

var := ""
DriveGet(var, "List", "")
Assert(var != "", "'DriveGet List' failed")

Assert(A_YYYY "" == 2013 "", "The year has changed since 2013 :)")

Assert(A_WorkingDir != "", "A_WorkingDir is empty")

WD := A_WorkingDir
Assert(WD == A_WorkingDir, "Failed to set var to builtin var")

A_WorkingDir := A_WorkingDir . "/Tests"
Assert(A_WorkingDir == WD . "/Tests", "Failed to set A_WorkingDir")

Assert((5 < 3) ? false : true, "< failed")
Assert((5 < 3) "" == "0", "Bools as strings")

Assert((5 > 3) * 4 == 4, "Bool as int failed")

obj := { "a" : 4, 4 : 5, 5 : "a" }
Assert(obj != null, "Object literal failed")
Assert(obj.a "" == 4 "", "Object literal incorrect")

Assert(obj.b == null, "Retrieval of undefined object member failed")

obj.a += 5
Assert(obj.a "" == 9 "", "+= on obj member failed")

obj.a := "a"
Assert(obj.a == "a", "obj member assignment failed")

arr := [2, 4, 9]
Assert(arr != null, "Array literal failed")

; just testing for errors on empty literals
obj := {}
arr := []

a := 0
b := "b"
c := "c"
d := "d"
e := "e"
f := "f"
g := "g"

if (g) {
	Assert(g, "Assertion in if-Block failed")
}

; just a comment - divider

if (false) {
	throw "False is true"
} else {
	Assert(g, "Assertion in else-Block failed")
}

; todo: fix parsing so it works without parentheses
result := (a ? b ? c : d : e ? f : g)
Assert(result == "f", "Chained ternary failed")

a := b .= c
Assert(b == "bc", "chained concat-assign failed")
Assert(a == b, "chained assignment failed")

if (true) {
	return()
}
Assert(false, "conditional return in auto-execute failed")

Assert(cond, msg) {
	if (cond) {
		FileAppend("`tAssert (" cond ") : '" msg "'`n", "*")
	} else {
		throw(msg "")
	}
}

; truth values:
; ==========================================================
Assert(""    ? false : true, "Empty string is true")
Assert(0     ? false : true, "0 is true")
Assert(0.0   ? false : true, "0.0 is true")
Assert(false ? false : true, "false is true")
Assert(null  ? false : true, "null is true")
Assert(a     ? false : true, "Uninitialized var is not false")

Assert("a", "Non-empty string is false")
Assert(1, "1 is false")
Assert(true, "true is false")
Assert(!false, "!false is false")
; ==========================================================

Assert(0x2 "" == "2", "Hex-Int to string conversion failed")

five() {
	return(5)
}

Assert(five() "" == "5", "Return value failed")
Assert(5 ** 2 == 25.0, "Power failed")

cond() {
	if (true) {
		return(true)
	}
}
Assert(cond(), "function return in if failed")

glob := "var"
local_func() {
	Assert(local == null, "Uninit var in func was not null")
	local := true
	Assert(local, "Initialized local var in func failed")

	Assert(glob == null, "Global var was visible in function")
}
local_func()

c := 5
c += 8.2
Assert(c == 13.2, "+= failed")

; just testing if the expression isn't too long
b := 5
b .= ": " 5 + 8.2 " = " c " = " . 13.2 " != " 1 * 1 - 13.2 + 5.8 " + 4e-2 == " 0.001 * (0 + 1) * 10 ** 0 " += c"

var := ""
DriveGet(var, "List", "")
Assert(var != "", "'DriveGet List' failed")

Assert(A_YYYY "" == 2013 "", "The year has changed since 2013 :)")

Assert(A_WorkingDir != "", "A_WorkingDir is empty")

WD := A_WorkingDir
Assert(WD == A_WorkingDir, "Failed to set var to builtin var")

A_WorkingDir := A_WorkingDir . "/Tests"
Assert(A_WorkingDir == WD . "/Tests", "Failed to set A_WorkingDir")

Assert((5 < 3) ? false : true, "< failed")
Assert((5 < 3) "" == "0", "Bools as strings")

Assert((5 > 3) * 4 == 4, "Bool as int failed")

obj := { "a" : 4, 4 : 5, 5 : "a" }
Assert(obj != null, "Object literal failed")
Assert(obj.a "" == 4 "", "Object literal incorrect")

Assert(obj.b == null, "Retrieval of undefined object member failed")

obj.a += 5
Assert(obj.a "" == 9 "", "+= on obj member failed")

obj.a := "a"
Assert(obj.a == "a", "obj member assignment failed")

arr := [2, 4, 9]
Assert(arr != null, "Array literal failed")

; just testing for errors on empty literals
obj := {}
arr := []

a := 0
b := "b"
c := "c"
d := "d"
e := "e"
f := "f"
g := "g"

if (g) {
	Assert(g, "Assertion in if-Block failed")
}

; just a comment - divider

if (false) {
	throw "False is true"
} else {
	Assert(g, "Assertion in else-Block failed")
}

; todo: fix parsing so it works without parentheses
result := (a ? b ? c : d : e ? f : g)
Assert(result == "f", "Chained ternary failed")

a := b .= c
Assert(b == "bc", "chained concat-assign failed")
Assert(a == b, "chained assignment failed")

if (true) {
	return()
}
Assert(false, "conditional return in auto-execute failed")

Assert(cond, msg) {
	if (cond) {
		FileAppend("`tAssert (" cond ") : '" msg "'`n", "*")
	} else {
		throw(msg "")
	}
}


Add AddToGlobalMenu

Add AddToGlobalMenu

global g_GlobalMenuItems := ""

GlobalMenu:
    AddToGlobalMenu("查看剪切板内容", "Clip")
    ; AddToGlobalMenu("发送文件到记事本", "OpenWithNotepad", "Notepad++")

    WinGetClass, lastWindowClass, A

    for index, element in g_GlobalMenuItems
    {
        if (element[3] == "" || lastWindowClass == element[3])
        {
            Menu, GlobalMenu, Add, % element[1], % element[2]
        }
    }

    Menu, GlobalMenu, Show
    Menu, GlobalMenu, DeleteAll
return

AddToGlobalMenu(name, label, winClass := "")
{
    if (g_GlobalMenuItems == "")
    {
        g_GlobalMenuItems := Object()
    }

    g_GlobalMenuItems.Push([name, label, winClass])
}

OpenWithNotepad:
    WinGetTitle, title, A
    StringReplace, title, title, - Notepad++, , All

    Run, notepad "%title%"
return

GlobalMenu:
    Menu, ContextMenu, Add, 查看剪切板内容, Clip
    Menu, ContextMenu, Show
    Menu, ContextMenu, DeleteAll
return