Removed old Rainmeter hotkeys

Removed old Rainmeter hotkeys

;Control key Ctrl- ^
;Alt key Alt- !
;Shift key Shift- +
;Windows key Win- #

#Persistent
#SingleInstance Force
DetectHiddenWindows, On
DetectHiddenText, On
SetTitleMatchMode, RegEx ;match titles and classes using regular expressions
SetTitleMatchMode Slow ;match titles and classes using regular expressions
CoordMode, Mouse, Screen
CoordMode, ToolTip, Screen
OldTicks = 0

;check for cygwin path
global CygPath
CygPath = C:\Program Files (x86)\cygwin
IfNotExist %CygPath%
	CygPath = C:\Cygwin

global BrowserPath
BrowserPath = C:\Program Files (x86)\Mozilla Firefox\firefox.exe
IfNotExist %BrowserPath%
	BrowserPath = "C:\Users\rr-\AppData\Local\Google\Chrome\Application\chrome.exe"

global IMClass
global IMPath

;pidgin
IMClass := "Buddy List"
IMPath := "C:\Program Files (x86)\pidgin\pidgin.exe"
If !FileExist(IMPath) {
	;wtw
	IMClass := "ahk_class {B993D471-D465-43f2-BBA5-DEEA18A1789E}"
	IMPath := "C:\Program Files\WTW\WTW.exe"
	If !FileExist(IMPath) {
		IMPath := "C:\Program Files\K2T\WTW\WTW.exe"
	}
}

global MonitorWorkAreaLeft
global MonitorWorkAreaRight
global MonitorWorkAreaTop
global MonitorWorkAreaBottom
SysGet, MonitorPrimary, MonitorPrimary
SysGet, MonitorWorkArea, MonitorWorkArea, %MonitorPrimary%

;disable windows+l
RegWrite, REG_DWORD, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Policies\System, DisableLockWorkstation, 1

TermX := MonitorWorkAreaRight - 920
TermY := 45
RemoteTermX := 45
RemoteTermY := 45

;GroupAdd, adobe, ahk_class OWL.DocumentWindow
;GroupAdd, adobe, ahk_class illustrator
;GroupAdd, adobe, ahk_class PSViewC
;GroupAdd, adobe, ahk_class Photoshop
;GroupAdd, adobe, Photoshop

return

;replace stuff in clipboard when it changes
OnClipboardChange:
{
	if (A_EventInfo == 1) and (SubStr(clipboard, 1, 7) == "http://")
	{
		StringReplace, clipboard, clipboard, [, `%5b, All
		StringReplace, clipboard, clipboard, \, `%5c, All
		StringReplace, clipboard, clipboard, ], `%5d, All
	}
	return
}

;declare some fun functions...

;activate/run a program
FRun(window, path, folder)
{
	if (!window or !WinExist(window))
	{
		Run, %path%, %folder%
	}
	else
	{
		WinShow
		WinActivate
	}
	return
}

;create random file name
RandomFileName()
{
	FormatTime, fileName,, yyyyMMdd_HHmmss_
	characters := "abcdefghijklmnopqrstuvwxyz"
	Loop 3
	{
		Random, rand, 1, strlen(characters)
		fileName := fileName . substr(characters, rand, 1)
	}
	return fileName
}

;calling screen script
MakeScreen(arguments)
{
	baseFileName := "Z:\" . RandomFileName() . ".png"
	RunWait, % "Z:\software\utilities\scrsh.exe --path " . baseFileName . " " . arguments, "Z:\", Hide
	SoundPlay, Z:\clutter\sounds\ping.wav
	return baseFileName
}

;focus window in given direction
DirectionalFocus(direction)
{
	DetectHiddenWindows, Off
	ActiveHwnd := WinExist("A")
	WinGetPos bx, by, _, _, ahk_id %ActiveHwnd%
	WinGet windows, List
	Loop %windows%
	{
		id := windows%A_Index%
		WinGetPos wx, wy, _, _, ahk_id %id%

		if (direction == "left")
			condition := wx < bx
		else if (direction == "right")
			condition := wx > bx
		else if (direction == "up")
			condition := wy < by
		else if (direction == "down")
			condition := wy > by
		else
		{
			MsgBox % "Bad direction"
			return
		}
		if (condition)
		{
			WinGetTitle, wtitle, ahk_id %id%
			if (wtitle != "")
			{
				WinActivate, ahk_id %id%
				break
			}
		}
	}
	DetectHiddenWindows, On
	return
}

#If FileExist(CygPath)
	;cygwin - activate/run
	#Enter::
	{
		Run, %CygPath%\bin\mintty.exe --title "Terminal" --size "110`,35" --position "%TermX%`,%TermY%" --class "mintty_thetty" --exec /bin/zsh -l, %CygPath%
		return
	}
	+^![::
	{
		Run, %CygPath%\bin\mintty.exe --title "Terminal" --size "110`,35" --position "%TermX%`,%TermY%" --class "mintty_thetty" --exec /bin/zsh -l, %CygPath%
		return
	}
	^![::
	{
		if (!WinExist("ahk_class mintty_thetty"))
		{
			Run, %CygPath%\bin\mintty.exe --title "Terminal" --size "110`,35" --position "%TermX%`,%TermY%" --class "mintty_thetty" --exec /bin/zsh -c 'while /bin/true`; do /bin/zsh -l`; cygstart "%A_AhkPath%" "Z:\src\dotfiles\hide.ahk"`; clear; done', %CygPath%
			WinWait ahk_class mintty_thetty
		}
		else
		{
			WinShow
			WinActivate
		}
		return
	}
	;ssh to burza - activate/run
	+^!]::
	{
		Run, %CygPath%\bin\mintty.exe --title "Remote terminal" --size "190`,65" --position "%RemoteTermX%`,%RemoteTermY%" --class mintty_ssh --exec /bin/ssh -p 65000 rr-@sakuya.pl, %CygPath%/bin
		return
	}
	^!]::
	{
		if (!WinExist("ahk_class mintty_ssh"))
		{
			Run, %CygPath%\bin\mintty.exe --title "Remote terminal" --size "190`,65" --position "%RemoteTermX%`,%RemoteTermY%" --class mintty_ssh --exec /bin/ssh -p 65000 rr-@sakuya.pl, %CygPath%/bin
			WinWait ahk_class mintty_ssh
		}
		else
		{
			WinShow
			WinActivate
		}
		return
	}
	;text editor - activate/run + fix screen position
	+^!N::
	{
		IfWinExist, ahk_class Vim
		{
			WinShow
			WinActivate
		}
		else
		{
			Run, %CygPath%\bin\mintty.exe --size "180`,60" --position "100`,100" --class "Vim" --exec /bin/zsh -l -i -c /bin/vim, %CygPath%/bin
			WinWait, ahk_class Vim
		}
		return
	}
	+PrintScreen::MakeScreen("-g")
	!PrintScreen::MakeScreen("-r active-window --shift -8,-8,+16,+16 --force-gui")
	!#PrintScreen::MakeScreen("-r active-monitor")
	#PrintScreen::MakeScreen("-r all-monitors")

;explorer - activate/run
#E::FRun("ahk_class CabinetWClass", "Z:\", "Z:\")

;foobar - activate/run
#If FileExist("C:\program files (x86)\foobar2000\foobar2000.exe")
	Launch_Media::FRun("ahk_class {97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}", "C:\program files (x86)\foobar2000\foobar2000.exe", "C:\Program Files (x86)\foobar2000")

;foobar - media shortcuts
AppsKey::Send {AppsKey}
+AppsKey::Send +{AppsKey}
AppsKey & Insert::Send {Launch_Media}
AppsKey & Home::Send {Media_Prev}
AppsKey & End::Send {Media_Next}
AppsKey & Del::Send {Media_Play_Pause}
AppsKey & PgUp::Send {Volume_Up}
AppsKey & PgDn::Send {Volume_Down}

;im
#If FileExist(IMPath)
	;im - activate/run
	+^!M::
		if (!WinExist(IMClass))
		{
			Run, %IMPath% -x
		}
		else
		{
			WinShow
			WinActivate
		}
		return

;browser
#If FileExist(BrowserPath)
	;web browser - activate/run
	^!;::
		if WinExist("Mozilla Firefox")
		{
			WinShow
			WinActivate
			Send, !d
		}
		else if WinExist("Vimperator")
		{
			WinShow
			WinActivate
			Send, !d
		}
		else if WinExist("ahk_class Chrome_WidgetWin_1")
		{
			WinActivate
			ControlFocus, Chrome_OmniboxView1
			SendInput, {Home}+{End}
		}
		else
		{
			IfExist %BrowserPath%
				Run, %BrowserPath%
		}
		return

;windows powershell / cmd functionalities
#IfWinActive ahk_class ConsoleWindowClass
	+Insert::SendInput {Raw}%clipboard% ;paste on shift+insert
	+PgUp::SendInput ! {Up}{Up}{Up}{Right}{Up}{Up}{Enter}{PgUp}{Enter} ;scroll on shift+page up
	+PgDn::SendInput ! {Up}{Up}{Up}{Right}{Up}{Up}{Enter}{PgDn}{Enter} ;scroll on shift+page down
#IfWinActive

;other functionalities

;reload autohotkey
!F12::Reload

;maximize active window
!M::
	ActiveHwnd := WinExist("A")
	PostMessage 0x112, 0xf030 ;WM_SYSCOMMAND, SC_MAXIMIZE
	return

;restore active window
!R::
	ActiveHwnd := WinExist("A")
	PostMessage 0x112, 0xf120 ;WM_SYSCOMMAND, SC_RESTORE
	return

;minimize active window
!W::
	if WinActive("WTW$")
	{
		WinHide
	}
	else if WinActive("Buddy List")
	{
		WinHide
	}
	else
	{
		ActiveHwnd := WinExist("A")
		PostMessage 0x112, 0xF020 ;WM_SYSCOMMAND, SC_MINIMIZE
	}
	return

;always on top
!A::WinSet, AlwaysOnTop, Toggle, A

;transparency
#WheelUp::
	WinGet, Transparency, Transparent, A
	if ! Transparency
		Transparency = 255
	Transparency := Transparency + 16
	if Transparency <= 10
	{
		WinSet, Transparent, 10, A
	}
	else if Transparency >= 255
	{
		WinSet, Transparent, 255, A
		WinSet, Transparent, OFF, A
	}
	else
	{
		WinSet, Transparent, %Transparency%, A
	}
	return
#WheelDown::
	WinGet, Transparency, Transparent, A
	if ! Transparency
		Transparency = 255
	Transparency := Transparency - 16
	if Transparency <= 10
	{
		WinSet, Transparent, 10, A
	}
	else if Transparency >= 255
	{
		WinSet, Transparent, 255, A
		WinSet, Transparent, OFF, A
	}
	else
	{
		WinSet, Transparent, %Transparency%, A
	}
	return

;explorer
#IfWinActive ahk_class CabinetWClass
	;new folder
	^n::
		SendInput {Up}{Ctrl Down}{Space}{Ctrl Up}{AppsKey}{Up}{Up}{Right}{Enter}
		return
#IfWinActive

;adobe products
#IfWinActive ahk_group adobe
	~LAlt::return
	LAlt UP::Send {Escape}
#IfWinActive

;shortcuts like in i3
;close active window
#Q::
	ActiveHwnd := WinExist("A")
	WinClose
	return
#D::
	SendInput, {LWin down}r{LWin up}
	return
#F::
	ActiveHwnd := WinExist("A")
	PostMessage 0x112, 0xf030 ;WM_SYSCOMMAND, SC_MAXIMIZE
	return
#H::DirectionalFocus("left")
#J::DirectionalFocus("down")
#K::DirectionalFocus("up")
#L::DirectionalFocus("right")
#1::return
#2::return
#3::return
#4::return
#5::return
#6::return
#7::return
#8::return
#9::return
#0::return
+#H::SendInput, {LWin down}{LShift down}{Left}{LShift up}{LWin up}
+#L::SendInput, {LWin down}{LShift down}{Right}{LShift up}{LWin up}

;Control key Ctrl- ^
;Alt key Alt- !
;Shift key Shift- +
;Windows key Win- #

#Persistent
#SingleInstance Force
DetectHiddenWindows, On
DetectHiddenText, On
SetTitleMatchMode, RegEx ;match titles and classes using regular expressions
SetTitleMatchMode Slow ;match titles and classes using regular expressions
CoordMode, Mouse, Screen
CoordMode, ToolTip, Screen
OldTicks = 0

;check for cygwin path
global CygPath
CygPath = C:\Program Files (x86)\cygwin
IfNotExist %CygPath%
	CygPath = C:\Cygwin

global BrowserPath
BrowserPath = C:\Program Files (x86)\Mozilla Firefox\firefox.exe
IfNotExist %BrowserPath%
	BrowserPath = "C:\Users\rr-\AppData\Local\Google\Chrome\Application\chrome.exe"

global IMClass
global IMPath

;pidgin
IMClass := "Buddy List"
IMPath := "C:\Program Files (x86)\pidgin\pidgin.exe"
If !FileExist(IMPath) {
	;wtw
	IMClass := "ahk_class {B993D471-D465-43f2-BBA5-DEEA18A1789E}"
	IMPath := "C:\Program Files\WTW\WTW.exe"
	If !FileExist(IMPath) {
		IMPath := "C:\Program Files\K2T\WTW\WTW.exe"
	}
}

global MonitorWorkAreaLeft
global MonitorWorkAreaRight
global MonitorWorkAreaTop
global MonitorWorkAreaBottom
SysGet, MonitorPrimary, MonitorPrimary
SysGet, MonitorWorkArea, MonitorWorkArea, %MonitorPrimary%

;disable windows+l
RegWrite, REG_DWORD, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Policies\System, DisableLockWorkstation, 1

TermX := MonitorWorkAreaRight - 920
TermY := 45
RemoteTermX := 45
RemoteTermY := 45

;GroupAdd, adobe, ahk_class OWL.DocumentWindow
;GroupAdd, adobe, ahk_class illustrator
;GroupAdd, adobe, ahk_class PSViewC
;GroupAdd, adobe, ahk_class Photoshop
;GroupAdd, adobe, Photoshop

return

;replace stuff in clipboard when it changes
OnClipboardChange:
{
	if (A_EventInfo == 1) and (SubStr(clipboard, 1, 7) == "http://")
	{
		StringReplace, clipboard, clipboard, [, `%5b, All
		StringReplace, clipboard, clipboard, \, `%5c, All
		StringReplace, clipboard, clipboard, ], `%5d, All
	}
	return
}

;declare some fun functions...

;activate/run a program
FRun(window, path, folder)
{
	if (!window or !WinExist(window))
	{
		Run, %path%, %folder%
	}
	else
	{
		WinShow
		WinActivate
	}
	return
}

;create random file name
RandomFileName()
{
	FormatTime, fileName,, yyyyMMdd_HHmmss_
	characters := "abcdefghijklmnopqrstuvwxyz"
	Loop 3
	{
		Random, rand, 1, strlen(characters)
		fileName := fileName . substr(characters, rand, 1)
	}
	return fileName
}

;calling screen script
MakeScreen(arguments)
{
	baseFileName := "Z:\" . RandomFileName() . ".png"
	RunWait, % "Z:\software\utilities\scrsh.exe --path " . baseFileName . " " . arguments, "Z:\", Hide
	SoundPlay, Z:\clutter\sounds\ping.wav
	return baseFileName
}

;focus window in given direction
DirectionalFocus(direction)
{
	DetectHiddenWindows, Off
	ActiveHwnd := WinExist("A")
	WinGetPos bx, by, _, _, ahk_id %ActiveHwnd%
	WinGet windows, List
	Loop %windows%
	{
		id := windows%A_Index%
		WinGetPos wx, wy, _, _, ahk_id %id%

		if (direction == "left")
			condition := wx < bx
		else if (direction == "right")
			condition := wx > bx
		else if (direction == "up")
			condition := wy < by
		else if (direction == "down")
			condition := wy > by
		else
		{
			MsgBox % "Bad direction"
			return
		}
		if (condition)
		{
			WinGetTitle, wtitle, ahk_id %id%
			if (wtitle != "")
			{
				WinActivate, ahk_id %id%
				break
			}
		}
	}
	DetectHiddenWindows, On
	return
}

#If FileExist(CygPath)
	;cygwin - activate/run
	#Enter::
	{
		Run, %CygPath%\bin\mintty.exe --title "Terminal" --size "110`,35" --position "%TermX%`,%TermY%" --class "mintty_thetty" --exec /bin/zsh -l, %CygPath%
		return
	}
	+^![::
	{
		Run, %CygPath%\bin\mintty.exe --title "Terminal" --size "110`,35" --position "%TermX%`,%TermY%" --class "mintty_thetty" --exec /bin/zsh -l, %CygPath%
		return
	}
	^![::
	{
		if (!WinExist("ahk_class mintty_thetty"))
		{
			Run, %CygPath%\bin\mintty.exe --title "Terminal" --size "110`,35" --position "%TermX%`,%TermY%" --class "mintty_thetty" --exec /bin/zsh -c 'while /bin/true`; do /bin/zsh -l`; cygstart "%A_AhkPath%" "Z:\src\dotfiles\hide.ahk"`; clear; done', %CygPath%
			WinWait ahk_class mintty_thetty
		}
		else
		{
			WinShow
			WinActivate
		}
		return
	}
	;ssh to burza - activate/run
	+^!]::
	{
		Run, %CygPath%\bin\mintty.exe --title "Remote terminal" --size "190`,65" --position "%RemoteTermX%`,%RemoteTermY%" --class mintty_ssh --exec /bin/ssh -p 65000 rr-@sakuya.pl, %CygPath%/bin
		return
	}
	^!]::
	{
		if (!WinExist("ahk_class mintty_ssh"))
		{
			Run, %CygPath%\bin\mintty.exe --title "Remote terminal" --size "190`,65" --position "%RemoteTermX%`,%RemoteTermY%" --class mintty_ssh --exec /bin/ssh -p 65000 rr-@sakuya.pl, %CygPath%/bin
			WinWait ahk_class mintty_ssh
		}
		else
		{
			WinShow
			WinActivate
		}
		return
	}
	;text editor - activate/run + fix screen position
	+^!N::
	{
		IfWinExist, ahk_class Vim
		{
			WinShow
			WinActivate
		}
		else
		{
			Run, %CygPath%\bin\mintty.exe --size "180`,60" --position "100`,100" --class "Vim" --exec /bin/zsh -l -i -c /bin/vim, %CygPath%/bin
			WinWait, ahk_class Vim
		}
		return
	}
	+PrintScreen::MakeScreen("-g")
	!PrintScreen::MakeScreen("-r active-window --shift -8,-8,+16,+16 --force-gui")
	!#PrintScreen::MakeScreen("-r active-monitor")
	#PrintScreen::MakeScreen("-r all-monitors")

;explorer - activate/run
#E::FRun("ahk_class CabinetWClass", "Z:\", "Z:\")

;foobar - activate/run
#If FileExist("C:\program files (x86)\foobar2000\foobar2000.exe")
	Launch_Media::FRun("ahk_class {97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}", "C:\program files (x86)\foobar2000\foobar2000.exe", "C:\Program Files (x86)\foobar2000")

;foobar - media shortcuts
AppsKey::Send {AppsKey}
+AppsKey::Send +{AppsKey}
AppsKey & Insert::Send {Launch_Media}
AppsKey & Home::Send {Media_Prev}
AppsKey & End::Send {Media_Next}
AppsKey & Del::Send {Media_Play_Pause}
AppsKey & PgUp::Send {Volume_Up}
AppsKey & PgDn::Send {Volume_Down}

;im
#If FileExist(IMPath)
	;im - activate/run
	+^!M::
		if (!WinExist(IMClass))
		{
			Run, %IMPath% -x
		}
		else
		{
			WinShow
			WinActivate
		}
		return

;browser
#If FileExist(BrowserPath)
	;web browser - activate/run
	^!;::
		if WinExist("Mozilla Firefox")
		{
			WinShow
			WinActivate
			Send, !d
		}
		else if WinExist("Vimperator")
		{
			WinShow
			WinActivate
			Send, !d
		}
		else if WinExist("ahk_class Chrome_WidgetWin_1")
		{
			WinActivate
			ControlFocus, Chrome_OmniboxView1
			SendInput, {Home}+{End}
		}
		else
		{
			IfExist %BrowserPath%
				Run, %BrowserPath%
		}
		return

;windows powershell / cmd functionalities
#IfWinActive ahk_class ConsoleWindowClass
	+Insert::SendInput {Raw}%clipboard% ;paste on shift+insert
	+PgUp::SendInput ! {Up}{Up}{Up}{Right}{Up}{Up}{Enter}{PgUp}{Enter} ;scroll on shift+page up
	+PgDn::SendInput ! {Up}{Up}{Up}{Right}{Up}{Up}{Enter}{PgDn}{Enter} ;scroll on shift+page down
#IfWinActive

;other functionalities

;autohotkey - reload this script
!F11::
{
	Process, Close, Rainmeter.exe
	Run, C:\Program Files \Rainmeter\Rainmeter.exe
	return
}
!F12::Reload

;maximize active window
!M::
	ActiveHwnd := WinExist("A")
	PostMessage 0x112, 0xf030 ;WM_SYSCOMMAND, SC_MAXIMIZE
	return

;restore active window
!R::
	ActiveHwnd := WinExist("A")
	PostMessage 0x112, 0xf120 ;WM_SYSCOMMAND, SC_RESTORE
	return

;minimize active window
!W::
	if WinActive("WTW$")
	{
		WinHide
	}
	else if WinActive("Buddy List")
	{
		WinHide
	}
	else
	{
		ActiveHwnd := WinExist("A")
		PostMessage 0x112, 0xF020 ;WM_SYSCOMMAND, SC_MINIMIZE
	}
	return

;always on top
!A::WinSet, AlwaysOnTop, Toggle, A

;transparency
#WheelUp::
	WinGet, Transparency, Transparent, A
	if ! Transparency
		Transparency = 255
	Transparency := Transparency + 16
	if Transparency <= 10
	{
		WinSet, Transparent, 10, A
	}
	else if Transparency >= 255
	{
		WinSet, Transparent, 255, A
		WinSet, Transparent, OFF, A
	}
	else
	{
		WinSet, Transparent, %Transparency%, A
	}
	return
#WheelDown::
	WinGet, Transparency, Transparent, A
	if ! Transparency
		Transparency = 255
	Transparency := Transparency - 16
	if Transparency <= 10
	{
		WinSet, Transparent, 10, A
	}
	else if Transparency >= 255
	{
		WinSet, Transparent, 255, A
		WinSet, Transparent, OFF, A
	}
	else
	{
		WinSet, Transparent, %Transparency%, A
	}
	return

;explorer
#IfWinActive ahk_class CabinetWClass
	;new folder
	^n::
		SendInput {Up}{Ctrl Down}{Space}{Ctrl Up}{AppsKey}{Up}{Up}{Right}{Enter}
		return
#IfWinActive

;adobe products
#IfWinActive ahk_group adobe
	~LAlt::return
	LAlt UP::Send {Escape}
#IfWinActive

;shortcuts like in i3
;close active window
#Q::
	ActiveHwnd := WinExist("A")
	WinClose
	return
#D::
	SendInput, {LWin down}r{LWin up}
	return
#F::
	ActiveHwnd := WinExist("A")
	PostMessage 0x112, 0xf030 ;WM_SYSCOMMAND, SC_MAXIMIZE
	return
#H::DirectionalFocus("left")
#J::DirectionalFocus("down")
#K::DirectionalFocus("up")
#L::DirectionalFocus("right")
#1::return
#2::return
#3::return
#4::return
#5::return
#6::return
#7::return
#8::return
#9::return
#0::return
+#H::SendInput, {LWin down}{LShift down}{Left}{LShift up}{LWin up}
+#L::SendInput, {LWin down}{LShift down}{Right}{LShift up}{LWin up}


RunZ: no exiting when a msgbox exist

RunZ: no exiting when a msgbox exist

#NoEnv
#SingleInstance, Force
#NoTrayIcon

FileEncoding, utf-8
SendMode Input

; 自动生成的命令文件
global g_SearchFileList := A_ScriptDir . "\SearchFileList.txt"
; 配置文件
global g_ConfFile := A_ScriptDir . "\RunZ.ini"

if !FileExist(g_ConfFile)
{
    FileCopy, %g_ConfFile%.help.txt, %g_ConfFile%
}

global g_Conf := class_EasyINI(g_ConfFile)

; 所有命令
global g_Commands
; 当搜索无结果时使用的命令
global g_FallbackCommands
; 编辑框当前内容
global g_CurrentInput
; 当前匹配到的第一条命令
global g_CurrentCommand
; 当前匹配到的所有命令
global g_CurrentCommandList
; 是否启用 TCMatch
global g_EnableTCMatch = TCMatchOn(g_Conf.Config.TCMatchPath)
; 列表第一列的首字母或数字
global g_FirstChar := Asc(g_Conf.Gui.FirstChar)
; 在列表中显示的行数
global g_DisplayRows := g_Conf.Gui.DisplayRows
; 在列表中显示的文字列数（多出的会被截断）
global g_DisplayCols := g_Conf.Gui.DisplayCols
; 命令使用了显示框
global g_UseDisplay
; 历史命令
global g_HistoryCommands
; 当前输入命令的参数，数组，为了方便没有添加 g_ 前缀
global Arg

if (FileExist(g_SearchFileList))
{
    LoadFiles()
}
else
{
    GoSub, ReloadFiles
}

Gui, Main:Font, % "s" g_Conf.Gui.FontSize, % g_Conf.Gui.FontName
Gui, Main:Add, Edit, % "gProcessInputCommand vSearchArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
Gui, Main:Add, Edit, % "ReadOnly vDisplayArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.DisplayAreaHeight
        , % SearchCommand("", true)
if (g_Conf.Gui.ShowCurrentCommand)
{
    Gui, Main:Add, Edit, % "ReadOnly"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
}
Gui, Main:Show, , RunZ
if (g_Conf.Gui.HideTitle)
{
    WinSet, Style, -0xC00000, A
}

if (g_Conf.Config.ExitIfInactivate)
{
    OnMessage(0x06, "WM_ACTIVATE")
}

Hotkey, IfWinActive, RunZ
; 如果是 ~enter，有时候会响
Hotkey, enter, RunCurrentCommand
Hotkey, ^j, ClearInput
Hotkey, f1, Help
Hotkey, f2, EditConfig
Hotkey, esc, ExitRunZ
Hotkey, ^d, OpenCurrentFileDir
Hotkey, ^x, DeleteCurrentFile
Hotkey, ^s, ShowCurrentFile
Hotkey, ^r, ReloadFiles
Hotkey, ^h, DisplayHistoryCommands

if (g_Conf.Config.RunInBackground)
{
    Hotkey, esc, WindowMin
}

Loop, % g_DisplayRows
{
    key := Chr(g_FirstChar + A_Index - 1)
    ; lalt +
    Hotkey, <!%key%, RunSelectedCommand1
    ; tab +
    Hotkey, ~%key%, RunSelectedCommand2
    ; shift +
    Hotkey, ~+%key%, IncreaseRank
}

if (g_Conf.Config.SaveInputText && g_Conf.Auto.InputText != "")
{
    Send, % g_Conf.Auto.InputText
}

if (g_Conf.Config.SaveHistory)
{
    g_HistoryCommands := Object()
    LoadHistoryCommands()
}

return

ExitRunZ:
    saveConf := false

    if (g_Conf.Config.SaveInputText)
    {
        g_Conf.DeleteKey("Auto", "InputText")
        g_Conf.AddKey("Auto", "InputText", g_CurrentInput)
        saveConf := true
    }

    if (g_Conf.Config.SaveHistory)
    {
        g_Conf.DeleteSection("History")
        g_Conf.AddSection("History")

        for index, element in g_HistoryCommands
        {
            g_Conf.AddKey("History", index, element)
        }

        saveConf := true
    }

    if (g_Conf.AutoRank)
    {
        saveConf := true
    }

    if (saveConf)
    {
        g_Conf.Save()
    }

    ExitApp
return

WindowMin:
    WinMinimize, A
return

GenerateSearchFileList()
{
    FileDelete, %g_SearchFileList%

    searchFileType := g_Conf.Config.SearchFileType

    for dirIndex, dir in StrSplit(g_Conf.Config.SearchFileDir, " | ")
    {
        if (InStr(dir, "A_") == 1)
        {
            searchPath := %dir%
        }
        else
        {
            searchPath := dir
        }

        for extIndex, ext in StrSplit(searchFileType, " | ")
        {
            Loop, Files, %searchPath%\%ext%, R
            {
                if (g_Conf.Config.SearchFileExclude != ""
                        && RegexMatch(A_LoopFileLongPath, g_Conf.Config.SearchFileExclude))
                {
                    continue
                }
                FileAppend, file | %A_LoopFileLongPath%`n, %g_SearchFileList%,
            }
        }
    }
}

ReloadFiles:
    GenerateSearchFileList()

    LoadFiles()
return

ProcessInputCommand:
    GuiControlGet, g_CurrentInput, , SearchArea
    SearchCommand(g_CurrentInput)
return

SearchCommand(command = "", firstRun = false)
{
    static useFallbackCommands
    result := ""
    ; 供去重使用
    fullResult := ""
    commandPrefix := SubStr(command, 1, 1)

    if (commandPrefix == ";" || commandPrefix == ":")
    {
        if (commandPrefix == ";")
        {
            g_CurrentCommand := g_FallbackCommands[1]
        }
        else if (commandPrefix == ":")
        {
            g_CurrentCommand := g_FallbackCommands[2]
        }

        g_CurrentCommandList.Push(g_CurrentCommand)
        result .= "a | " . g_CurrentCommand
        Arg := SubStr(g_CurrentInput, 2)
        DisplaySearchResult(result)
        return result
    }
    ; 用空格来判断参数
    else if (InStr(command, " ") && g_CurrentCommand != "")
    {
        if (useFallbackCommands)
        {
            Arg := command
        }
        else
        {
            Arg := SubStr(command, InStr(command, " ") + 1)
        }
        return
    }

    g_CurrentCommandList := Object()

    order := g_FirstChar

    for index, element in g_Commands
    {
        if (InStr(fullResult, element "`n"))
        {
            continue
        }

        splitedElement := StrSplit(element, " | ")

        if (splitedElement[1] == "file")
        {
            SplitPath, % splitedElement[2], , fileDir, , fileNameNoExt

            ; 只搜索和展示不带扩展名的文件名
            elementToSearch := fileNameNoExt
            elementToShow := "file | " . fileNameNoExt

            if (splitedElement.Length() >= 3)
            {
                elementToSearch .= " " . splitedElement[3]
                elementToShow .= "（" . splitedElement[3] . "）"
            }

            elementToShow := SubStr(elementToShow, 1, g_DisplayCols)

            if (g_Conf.Config.SearchFullPath)
            {
                ; TCMatch 在搜索路径时只搜索文件名，强行将 \ 转成空格
                elementToSearch := StrReplace(fileDir, "\", " ") . " " . elementToSearch
            }
        }
        else
        {
            elementToShow := SubStr(element, 1, g_DisplayCols)
            elementToSearch := splitedElement[2]
        }

        if (MatchCommand(elementToSearch, command))
        {
            fullResult .= element "`n"
            g_CurrentCommandList.Push(element)

            if (order == g_FirstChar)
            {
                g_CurrentCommand := element
            }
            else
            {
                result .= "`n"
            }

            result .= Chr(order++) . " | " . elementToShow

            if (order - g_FirstChar >= g_DisplayRows)
            {
                break
            }
            ; 第一次运行只加载 function 类型
            if (firstRun && (order - g_FirstChar >= g_DisplayRows - 4))
            {
                result .= "`n`n现有 " g_Commands.Length() " 条命令。"
                result .= "`n`n键入内容 搜索，回车 执行第一条，Alt + 字母 执行，F1 帮助，Esc 退出。"

                break
            }
        }
    }

    if (result == "")
    {
        useFallbackCommands := true
        g_CurrentCommand := g_FallbackCommands[1]
        g_CurrentCommandList := g_FallbackCommands
        Arg := g_CurrentInput

        for index, element in g_FallbackCommands
        {
            if (index != 1)
            {
                result .= "`n"
            }

            result .= Chr(g_FirstChar - 1 + index++) . " | " . element
        }
    }
    else
    {
        useFallbackCommands := false
    }

    DisplaySearchResult(result)
    return result
}

DisplaySearchResult(result)
{
    DisplayText(result)

    if (g_CurrentCommandList.Length() == 1 && g_Conf.Config.RunIfOnlyOne)
    {
        GoSub, RunCurrentCommand
    }

    if (g_Conf.Gui.ShowCurrentCommand)
    {
        ControlSetText, Edit3, %g_CurrentCommand%
    }
}

ClearInput:
    ControlSetText, Edit1,
return

RunCurrentCommand:
    if (GetInputState() == 1)
    {
        Send, {enter}
    }

    if (g_CurrentInput != "")
    {
        g_UseDisplay := false

        RunCommand(g_CurrentCommand)
        if (g_Conf.Config.RunOnce && !g_UseDisplay)
        {
            GoSub, ExitRunZ
        }
    }
return

MatchCommand(Haystack, Needle)
{
    if (g_EnableTCMatch)
    {
        return TCMatch(Haystack, Needle)
    }

    return InStr(Haystack, Needle)
}

RunCommand(originCmd)
{
    splitedOriginCmd := StrSplit(originCmd, " | ")
    ; 去掉括号内的注释
    cmd := StrSplit(splitedOriginCmd[2], "（")[1]

    if (splitedOriginCmd[1] == "file" || splitedOriginCmd[1] == "url")
    {
        if (InStr(cmd, ".lnk"))
        {
            ; 处理 32 位 ahk 运行不了某些 64 位系统 .lnk 的问题
            FileGetShortcut, %cmd%, filePath
            if (!FileExist(filePath))
            {
                filePath := StrReplace(filePath, "C:\Program Files (x86)", "C:\Program Files")
                if (FileExist(filePath))
                {
                    cmd := filePath
                }
            }
        }

        Run, %cmd%
    }
    else if (splitedOriginCmd[1] == "function")
    {
        if (splitedOriginCmd.Length() >= 3)
        {
            Arg := splitedOriginCmd[3]
        }

        if (IsLabel(cmd))
        {
            GoSub, %cmd%
        }
    }
    else if (splitedOriginCmd[1] == "cmd")
    {
        RunWithCmd(cmd)
    }

    if (g_Conf.Config.SaveHistory && cmd != "DisplayHistoryCommands")
    {
        if (splitedOriginCmd.Length() == 2 && Arg != "")
        {
            g_HistoryCommands.InsertAt(1, originCmd " | " Arg)
        }
        else
        {
            g_HistoryCommands.InsertAt(1, originCmd)
        }

        if (g_HistoryCommands.Length() > g_Conf.Config.HistorySize)
        {
            g_HistoryCommands.Pop()
        }
    }

    if (g_Conf.Config.AutoRank)
    {
        IncreaseRank(originCmd)
    }
}

IncreaseRank(cmd, show = false)
{
    splitedCmd := StrSplit(cmd, " | ")

    if (splitedCmd.Length() >= 3)
    {
        ; 去掉参数
        cmd := splitedCmd[1]  " | " splitedCmd[2]
    }

    cmdRank := g_Conf.GetValue("Rank", cmd)
    if cmdRank is integer
    {
        g_Conf.DeleteKey("Rank", cmd)
        cmdRank++
    }
    else
    {
        cmdRank := 1
    }

    g_Conf.AddKey("Rank", cmd, cmdRank)

    if (show)
    {
        ToolTip, 增加 %cmd% 的权重到 %cmdRank%
        SetTimer, RemoveToolTip, 800
    }
}

RunSelectedCommand1:
    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

RunSelectedCommand2:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 2, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

IncreaseRank:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    if (g_CurrentCommandList[index] != "")
    {
        IncreaseRank(g_CurrentCommandList[index], true)
        LoadFiles()
    }
return

LoadFiles()
{
    g_Commands := Object()
    g_FallbackCommands := Object()

    rankString := ""
    for command, rank in g_Conf.Rank
    {
        rankString .= rank "`t" command "`n"
    }

    if (rankString != "")
    {
        Sort, rankString, R N

        Loop, Parse, rankString, `n
        {
            if (A_LoopField == "")
            {
                continue
            }

            g_Commands.Push(StrSplit(A_loopField, "`t")[2])
        }
    }

    for key, value in g_Conf.Command
    {
        if (value != "")
        {
            g_Commands.Push(key . "（" . value "）")
        }
        else
        {
            g_Commands.Push(key)
        }
    }

    if (FileExist(A_ScriptDir "\UserFunctions.ahk"))
    {
        userFunctionLabel := "UserFunctions"
        if (IsLabel(userFunctionLabel))
        {
            GoSub, %userFunctionLabel%
        }
        else
        {
            MsgBox, 未在 %A_ScriptDir%\UserFunctions.ahk 中发现 %userFunctionLabel% 标签，请修改！
        }
    }

    GoSub, Functions

    Loop, Read, %g_SearchFileList%
    {
        g_Commands.Push(A_LoopReadLine)
    }

    if (g_Conf.Config.LoadControlPanelFunctions)
    {
        Loop, Read, %A_ScriptDir%\ControlPanelFunctions.txt
        {
            g_Commands.Push(A_LoopReadLine)
        }
    }
}

DisplayText(text)
{
    textToDisplay := StrReplace(text, "`n", "`r`n")
    ControlSetText, Edit2, %textToDisplay%
}

DisplayResult(result)
{
    DisplayText(result)
    g_UseDisplay := true
}

LoadHistoryCommands()
{
    for key, value in g_Conf.History
    {
        g_HistoryCommands.Push(value)
    }
}

DisplayHistoryCommands:
    result := ""
    g_CurrentCommandList := Object()

    for index, element in g_HistoryCommands
    {
        result .= Chr(g_FirstChar + index - 1) . " | " . element "`n"

        if (index == 1)
        {
            g_CurrentCommand := element
        }

        g_CurrentCommandList.Push(element)
    }

    DisplayResult(result)
return

; AddFunction(label, info, fallback)
@(label, info, fallback = false)
{
    if (!IsLabel(label))
    {
        MsgBox, 未找到 %label% 标签，请检查 %A_ScriptDir%\UserFunctions.ahk 文件格式！
        return
    }

    g_Commands.Push("function | " . label . "（" . info . "）")
    if (fallback)
    {
        g_FallbackCommands.Push("function | " . label . "（" . info . "）")
    }
}

RunAndGetOutput(command)
{
    tempFileName := "RunZ.stdout.log"
    fullCommand = bash -c "%command% &> %tempFileName%"

    if (!FileExist("c:\msys64\usr\bin\bash.exe"))
    {
        fullCommand = %ComSpec% /C "%command% > %tempFileName%"
    }

    RunWait, %fullCommand%, %A_Temp%, Hide
    FileRead, result, %A_Temp%\%tempFileName%
    FileDelete, %A_Temp%\%tempFileName%
    return result
}

RunWithCmd(command)
{
    if (FileExist("c:\msys64\usr\bin\mintty.exe"))
    {
        Run, % "mintty -e sh -c '" command "; read'"
    }
    else
    {
        Run, % ComSpec " /C " command " & pause"
    }
}

OpenPath(filePath)
{
    if (!FileExist(filePath))
    {
        return
    }

    if (FileExist(g_Conf.Config.TCPath))
    {
        TCPath := g_Conf.Config.TCPath
        Run, %TCPath% /O /A /L="%filePath%"
    }
    else
    {
        SplitPath, filePath, , fileDir, ,
        Run, explorer "%fileDir%"
    }
}

GetAllFunctions()
{
    result := ""

    for index, element in g_Commands
    {
        if (InStr(element, "function | ") == 1)
        {
            result .= element "`n"
        }
    }

    return result
}

OpenCurrentFileDir:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]
    OpenPath(filePath)
return

DeleteCurrentFile:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]

    if (!FileExist(filePath))
    {
        return
    }

    FileRecycle, % filePath
    GoSub, ReloadFiles
return

ShowCurrentFile:
    clipboard := StrSplit(g_CurrentCommand, " | ")[2]
    ToolTip, % clipboard
    SetTimer, RemoveToolTip, 800
return

RemoveToolTip:
    ToolTip
    SetTimer, RemoveToolTip, Off
return

WM_ACTIVATE(wParam, lParam)
{
    if (wParam >= 1) ; 窗口激活
    {
        return
    }
    else if (wParam <= 0) ; 窗口非激活
    {
        SetTimer, ToExit, 50
    }
}

ToExit:
    if (!WinExist("RunZ.ahk"))
    {
        GoSub, ExitRunZ
    }

    SetTimer, ToExit, Off
return

UrlDownloadToString(url)
{
	static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	whr.Open("GET", url, true)
	whr.Send()
	whr.WaitForResponse()
	return whr.ResponseText
}

; 修改自万年书妖的 Candy 里的 SksSub_UrlEncode 函数，用于转换编码。感谢！
UrlEncode(url, enc = "UTF-8")
{
    enc := trim(enc)
    If enc=
        return url
    formatInteger := A_FormatInteger
    SetFormat, IntegerFast, H
    VarSetCapacity(buff, StrPut(url, enc))
    Loop % StrPut(url, &buff, enc) - 1
    {
        byte := NumGet(buff, A_Index-1, "UChar")
        encoded .= byte > 127 or byte <33 ? "%" Substr(byte, 3) : Chr(byte)
    }
    SetFormat, IntegerFast, %formatInteger%
    return encoded
}

; 0：英文 1：中文
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
}

#include %A_ScriptDir%\..\lib\class_EasyIni.ahk
#include %A_ScriptDir%\lib\Kanji\Kanji.ahk
#include %A_ScriptDir%\lib\TCMatch.ahk
#include %A_ScriptDir%\lib\Eval.ahk
#include %A_ScriptDir%\lib\JSON.ahk
#include %A_ScriptDir%\Functions.ahk
; 用户自定义命令
#include *i %A_ScriptDir%\UserFunctions.ahk

#NoEnv
#SingleInstance, Force
#NoTrayIcon

FileEncoding, utf-8
SendMode Input

; 自动生成的命令文件
global g_SearchFileList := A_ScriptDir . "\SearchFileList.txt"
; 配置文件
global g_ConfFile := A_ScriptDir . "\RunZ.ini"

if !FileExist(g_ConfFile)
{
    FileCopy, %g_ConfFile%.help.txt, %g_ConfFile%
}

global g_Conf := class_EasyINI(g_ConfFile)

; 所有命令
global g_Commands
; 当搜索无结果时使用的命令
global g_FallbackCommands
; 编辑框当前内容
global g_CurrentInput
; 当前匹配到的第一条命令
global g_CurrentCommand
; 当前匹配到的所有命令
global g_CurrentCommandList
; 是否启用 TCMatch
global g_EnableTCMatch = TCMatchOn(g_Conf.Config.TCMatchPath)
; 列表第一列的首字母或数字
global g_FirstChar := Asc(g_Conf.Gui.FirstChar)
; 在列表中显示的行数
global g_DisplayRows := g_Conf.Gui.DisplayRows
; 在列表中显示的文字列数（多出的会被截断）
global g_DisplayCols := g_Conf.Gui.DisplayCols
; 命令使用了显示框
global g_UseDisplay
; 历史命令
global g_HistoryCommands
; 当前输入命令的参数，数组，为了方便没有添加 g_ 前缀
global Arg

if (FileExist(g_SearchFileList))
{
    LoadFiles()
}
else
{
    GoSub, ReloadFiles
}

Gui, Main:Font, % "s" g_Conf.Gui.FontSize, % g_Conf.Gui.FontName
Gui, Main:Add, Edit, % "gProcessInputCommand vSearchArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
Gui, Main:Add, Edit, % "ReadOnly vDisplayArea"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.DisplayAreaHeight
        , % SearchCommand("", true)
if (g_Conf.Gui.ShowCurrentCommand)
{
    Gui, Main:Add, Edit, % "ReadOnly"
        . " w" g_Conf.Gui.WidgetWidth " h" g_Conf.Gui.EditHeight,
}
Gui, Main:Show, , RunZ
if (g_Conf.Gui.HideTitle)
{
    WinSet, Style, -0xC00000, A
}

if (g_Conf.Config.ExitIfInactivate)
{
    OnMessage(0x06, "WM_ACTIVATE")
}

Hotkey, IfWinActive, RunZ
; 如果是 ~enter，有时候会响
Hotkey, enter, RunCurrentCommand
Hotkey, ^j, ClearInput
Hotkey, f1, Help
Hotkey, f2, EditConfig
Hotkey, esc, ExitRunZ
Hotkey, ^d, OpenCurrentFileDir
Hotkey, ^x, DeleteCurrentFile
Hotkey, ^s, ShowCurrentFile
Hotkey, ^r, ReloadFiles
Hotkey, ^h, DisplayHistoryCommands

if (g_Conf.Config.RunInBackground)
{
    Hotkey, esc, WindowMin
}

Loop, % g_DisplayRows
{
    key := Chr(g_FirstChar + A_Index - 1)
    ; lalt +
    Hotkey, <!%key%, RunSelectedCommand1
    ; tab +
    Hotkey, ~%key%, RunSelectedCommand2
    ; shift +
    Hotkey, ~+%key%, IncreaseRank
}

if (g_Conf.Config.SaveInputText && g_Conf.Auto.InputText != "")
{
    Send, % g_Conf.Auto.InputText
}

if (g_Conf.Config.SaveHistory)
{
    g_HistoryCommands := Object()
    LoadHistoryCommands()
}

return

ExitRunZ:
    saveConf := false

    if (g_Conf.Config.SaveInputText)
    {
        g_Conf.DeleteKey("Auto", "InputText")
        g_Conf.AddKey("Auto", "InputText", g_CurrentInput)
        saveConf := true
    }

    if (g_Conf.Config.SaveHistory)
    {
        g_Conf.DeleteSection("History")
        g_Conf.AddSection("History")

        for index, element in g_HistoryCommands
        {
            g_Conf.AddKey("History", index, element)
        }

        saveConf := true
    }

    if (g_Conf.AutoRank)
    {
        saveConf := true
    }

    if (saveConf)
    {
        g_Conf.Save()
    }

    ExitApp
return

WindowMin:
    WinMinimize, A
return

GenerateSearchFileList()
{
    FileDelete, %g_SearchFileList%

    searchFileType := g_Conf.Config.SearchFileType

    for dirIndex, dir in StrSplit(g_Conf.Config.SearchFileDir, " | ")
    {
        if (InStr(dir, "A_") == 1)
        {
            searchPath := %dir%
        }
        else
        {
            searchPath := dir
        }

        for extIndex, ext in StrSplit(searchFileType, " | ")
        {
            Loop, Files, %searchPath%\%ext%, R
            {
                if (g_Conf.Config.SearchFileExclude != ""
                        && RegexMatch(A_LoopFileLongPath, g_Conf.Config.SearchFileExclude))
                {
                    continue
                }
                FileAppend, file | %A_LoopFileLongPath%`n, %g_SearchFileList%,
            }
        }
    }
}

ReloadFiles:
    GenerateSearchFileList()

    LoadFiles()
return

ProcessInputCommand:
    GuiControlGet, g_CurrentInput, , SearchArea
    SearchCommand(g_CurrentInput)
return

SearchCommand(command = "", firstRun = false)
{
    static useFallbackCommands
    result := ""
    ; 供去重使用
    fullResult := ""
    commandPrefix := SubStr(command, 1, 1)

    if (commandPrefix == ";" || commandPrefix == ":")
    {
        if (commandPrefix == ";")
        {
            g_CurrentCommand := g_FallbackCommands[1]
        }
        else if (commandPrefix == ":")
        {
            g_CurrentCommand := g_FallbackCommands[2]
        }

        g_CurrentCommandList.Push(g_CurrentCommand)
        result .= "a | " . g_CurrentCommand
        Arg := SubStr(g_CurrentInput, 2)
        DisplaySearchResult(result)
        return result
    }
    ; 用空格来判断参数
    else if (InStr(command, " ") && g_CurrentCommand != "")
    {
        if (useFallbackCommands)
        {
            Arg := command
        }
        else
        {
            Arg := SubStr(command, InStr(command, " ") + 1)
        }
        return
    }

    g_CurrentCommandList := Object()

    order := g_FirstChar

    for index, element in g_Commands
    {
        if (InStr(fullResult, element "`n"))
        {
            continue
        }

        splitedElement := StrSplit(element, " | ")

        if (splitedElement[1] == "file")
        {
            SplitPath, % splitedElement[2], , fileDir, , fileNameNoExt

            ; 只搜索和展示不带扩展名的文件名
            elementToSearch := fileNameNoExt
            elementToShow := "file | " . fileNameNoExt

            if (splitedElement.Length() >= 3)
            {
                elementToSearch .= " " . splitedElement[3]
                elementToShow .= "（" . splitedElement[3] . "）"
            }

            elementToShow := SubStr(elementToShow, 1, g_DisplayCols)

            if (g_Conf.Config.SearchFullPath)
            {
                ; TCMatch 在搜索路径时只搜索文件名，强行将 \ 转成空格
                elementToSearch := StrReplace(fileDir, "\", " ") . " " . elementToSearch
            }
        }
        else
        {
            elementToShow := SubStr(element, 1, g_DisplayCols)
            elementToSearch := splitedElement[2]
        }

        if (MatchCommand(elementToSearch, command))
        {
            fullResult .= element "`n"
            g_CurrentCommandList.Push(element)

            if (order == g_FirstChar)
            {
                g_CurrentCommand := element
            }
            else
            {
                result .= "`n"
            }

            result .= Chr(order++) . " | " . elementToShow

            if (order - g_FirstChar >= g_DisplayRows)
            {
                break
            }
            ; 第一次运行只加载 function 类型
            if (firstRun && (order - g_FirstChar >= g_DisplayRows - 4))
            {
                result .= "`n`n现有 " g_Commands.Length() " 条命令。"
                result .= "`n`n键入内容 搜索，回车 执行第一条，Alt + 字母 执行，F1 帮助，Esc 退出。"

                break
            }
        }
    }

    if (result == "")
    {
        useFallbackCommands := true
        g_CurrentCommand := g_FallbackCommands[1]
        g_CurrentCommandList := g_FallbackCommands
        Arg := g_CurrentInput

        for index, element in g_FallbackCommands
        {
            if (index != 1)
            {
                result .= "`n"
            }

            result .= Chr(g_FirstChar - 1 + index++) . " | " . element
        }
    }
    else
    {
        useFallbackCommands := false
    }

    DisplaySearchResult(result)
    return result
}

DisplaySearchResult(result)
{
    DisplayText(result)

    if (g_CurrentCommandList.Length() == 1 && g_Conf.Config.RunIfOnlyOne)
    {
        GoSub, RunCurrentCommand
    }

    if (g_Conf.Gui.ShowCurrentCommand)
    {
        ControlSetText, Edit3, %g_CurrentCommand%
    }
}

ClearInput:
    ControlSetText, Edit1,
return

RunCurrentCommand:
    if (GetInputState() == 1)
    {
        Send, {enter}
    }

    if (g_CurrentInput != "")
    {
        g_UseDisplay := false

        RunCommand(g_CurrentCommand)
        if (g_Conf.Config.RunOnce && !g_UseDisplay)
        {
            GoSub, ExitRunZ
        }
    }
return

MatchCommand(Haystack, Needle)
{
    if (g_EnableTCMatch)
    {
        return TCMatch(Haystack, Needle)
    }

    return InStr(Haystack, Needle)
}

RunCommand(originCmd)
{
    splitedOriginCmd := StrSplit(originCmd, " | ")
    ; 去掉括号内的注释
    cmd := StrSplit(splitedOriginCmd[2], "（")[1]

    if (splitedOriginCmd[1] == "file" || splitedOriginCmd[1] == "url")
    {
        if (InStr(cmd, ".lnk"))
        {
            ; 处理 32 位 ahk 运行不了某些 64 位系统 .lnk 的问题
            FileGetShortcut, %cmd%, filePath
            if (!FileExist(filePath))
            {
                filePath := StrReplace(filePath, "C:\Program Files (x86)", "C:\Program Files")
                if (FileExist(filePath))
                {
                    cmd := filePath
                }
            }
        }

        Run, %cmd%
    }
    else if (splitedOriginCmd[1] == "function")
    {
        if (splitedOriginCmd.Length() >= 3)
        {
            Arg := splitedOriginCmd[3]
        }

        if (IsLabel(cmd))
        {
            GoSub, %cmd%
        }
    }
    else if (splitedOriginCmd[1] == "cmd")
    {
        RunWithCmd(cmd)
    }

    if (g_Conf.Config.SaveHistory && cmd != "DisplayHistoryCommands")
    {
        if (splitedOriginCmd.Length() == 2 && Arg != "")
        {
            g_HistoryCommands.InsertAt(1, originCmd " | " Arg)
        }
        else
        {
            g_HistoryCommands.InsertAt(1, originCmd)
        }

        if (g_HistoryCommands.Length() > g_Conf.Config.HistorySize)
        {
            g_HistoryCommands.Pop()
        }
    }

    if (g_Conf.Config.AutoRank)
    {
        IncreaseRank(originCmd)
    }
}

IncreaseRank(cmd, show = false)
{
    splitedCmd := StrSplit(cmd, " | ")

    if (splitedCmd.Length() >= 3)
    {
        ; 去掉参数
        cmd := splitedCmd[1]  " | " splitedCmd[2]
    }

    cmdRank := g_Conf.GetValue("Rank", cmd)
    if cmdRank is integer
    {
        g_Conf.DeleteKey("Rank", cmd)
        cmdRank++
    }
    else
    {
        cmdRank := 1
    }

    g_Conf.AddKey("Rank", cmd, cmdRank)

    if (show)
    {
        ToolTip, 增加 %cmd% 的权重到 %cmdRank%
        SetTimer, RemoveToolTip, 800
    }
}

RunSelectedCommand1:
    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

RunSelectedCommand2:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 2, 1)) - g_FirstChar + 1

    RunCommand(g_CurrentCommandList[index])
return

IncreaseRank:
    ControlGetFocus, ctrl,
    if (ctrl == "Edit1")
    {
        return
    }

    index := Asc(SubStr(A_ThisHotkey, 3, 1)) - g_FirstChar + 1

    if (g_CurrentCommandList[index] != "")
    {
        IncreaseRank(g_CurrentCommandList[index], true)
        LoadFiles()
    }
return

LoadFiles()
{
    g_Commands := Object()
    g_FallbackCommands := Object()

    rankString := ""
    for command, rank in g_Conf.Rank
    {
        rankString .= rank "`t" command "`n"
    }

    if (rankString != "")
    {
        Sort, rankString, R N

        Loop, Parse, rankString, `n
        {
            if (A_LoopField == "")
            {
                continue
            }

            g_Commands.Push(StrSplit(A_loopField, "`t")[2])
        }
    }

    for key, value in g_Conf.Command
    {
        if (value != "")
        {
            g_Commands.Push(key . "（" . value "）")
        }
        else
        {
            g_Commands.Push(key)
        }
    }

    if (FileExist(A_ScriptDir "\UserFunctions.ahk"))
    {
        userFunctionLabel := "UserFunctions"
        if (IsLabel(userFunctionLabel))
        {
            GoSub, %userFunctionLabel%
        }
        else
        {
            MsgBox, 未在 %A_ScriptDir%\UserFunctions.ahk 中发现 %userFunctionLabel% 标签，请修改！
        }
    }

    GoSub, Functions

    Loop, Read, %g_SearchFileList%
    {
        g_Commands.Push(A_LoopReadLine)
    }

    if (g_Conf.Config.LoadControlPanelFunctions)
    {
        Loop, Read, %A_ScriptDir%\ControlPanelFunctions.txt
        {
            g_Commands.Push(A_LoopReadLine)
        }
    }
}

DisplayText(text)
{
    textToDisplay := StrReplace(text, "`n", "`r`n")
    ControlSetText, Edit2, %textToDisplay%
}

DisplayResult(result)
{
    DisplayText(result)
    g_UseDisplay := true
}

LoadHistoryCommands()
{
    for key, value in g_Conf.History
    {
        g_HistoryCommands.Push(value)
    }
}

DisplayHistoryCommands:
    result := ""
    g_CurrentCommandList := Object()

    for index, element in g_HistoryCommands
    {
        result .= Chr(g_FirstChar + index - 1) . " | " . element "`n"

        if (index == 1)
        {
            g_CurrentCommand := element
        }

        g_CurrentCommandList.Push(element)
    }

    DisplayResult(result)
return

; AddFunction(label, info, fallback)
@(label, info, fallback = false)
{
    if (!IsLabel(label))
    {
        MsgBox, 未找到 %label% 标签，请检查 %A_ScriptDir%\UserFunctions.ahk 文件格式！
        return
    }

    g_Commands.Push("function | " . label . "（" . info . "）")
    if (fallback)
    {
        g_FallbackCommands.Push("function | " . label . "（" . info . "）")
    }
}

RunAndGetOutput(command)
{
    tempFileName := "RunZ.stdout.log"
    fullCommand = bash -c "%command% &> %tempFileName%"

    if (!FileExist("c:\msys64\usr\bin\bash.exe"))
    {
        fullCommand = %ComSpec% /C "%command% > %tempFileName%"
    }

    RunWait, %fullCommand%, %A_Temp%, Hide
    FileRead, result, %A_Temp%\%tempFileName%
    FileDelete, %A_Temp%\%tempFileName%
    return result
}

RunWithCmd(command)
{
    if (FileExist("c:\msys64\usr\bin\mintty.exe"))
    {
        Run, % "mintty -e sh -c '" command "; read'"
    }
    else
    {
        Run, % ComSpec " /C " command " & pause"
    }
}

OpenPath(filePath)
{
    if (!FileExist(filePath))
    {
        return
    }

    if (FileExist(g_Conf.Config.TCPath))
    {
        TCPath := g_Conf.Config.TCPath
        Run, %TCPath% /O /A /L="%filePath%"
    }
    else
    {
        SplitPath, filePath, , fileDir, ,
        Run, explorer "%fileDir%"
    }
}

GetAllFunctions()
{
    result := ""
    functionBegin := false

    for index, element in g_Commands
    {
        if (InStr(element, "function | ") == 1)
        {
            functionBegin := true
            result .= element "`n"
        }
        else if (functionBegin)
        {
            break
        }
    }

    return result
}

OpenCurrentFileDir:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]
    OpenPath(filePath)
return

DeleteCurrentFile:
    filePath := StrSplit(g_CurrentCommand, " | ")[2]

    if (!FileExist(filePath))
    {
        return
    }

    FileRecycle, % filePath
    GoSub, ReloadFiles
return

ShowCurrentFile:
    clipboard := StrSplit(g_CurrentCommand, " | ")[2]
    ToolTip, % clipboard
    SetTimer, RemoveToolTip, 800
return

RemoveToolTip:
    ToolTip
    SetTimer, RemoveToolTip, Off
return

WM_ACTIVATE(wParam, lParam)
{
    if (wParam >= 1) ; 窗口激活
    {
        return
    }
    else if (wParam <= 0) ; 窗口非激活
    {
        GoSub, ExitRunZ
    }
}

UrlDownloadToString(url)
{
	static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	whr.Open("GET", url, true)
	whr.Send()
	whr.WaitForResponse()
	return whr.ResponseText
}

; 修改自万年书妖的 Candy 里的 SksSub_UrlEncode 函数，用于转换编码。感谢！
UrlEncode(url, enc = "UTF-8")
{
    enc := trim(enc)
    If enc=
        return url
    formatInteger := A_FormatInteger
    SetFormat, IntegerFast, H
    VarSetCapacity(buff, StrPut(url, enc))
    Loop % StrPut(url, &buff, enc) - 1
    {
        byte := NumGet(buff, A_Index-1, "UChar")
        encoded .= byte > 127 or byte <33 ? "%" Substr(byte, 3) : Chr(byte)
    }
    SetFormat, IntegerFast, %formatInteger%
    return encoded
}

; 0：英文 1：中文
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
}

#include %A_ScriptDir%\..\lib\class_EasyIni.ahk
#include %A_ScriptDir%\lib\Kanji\Kanji.ahk
#include %A_ScriptDir%\lib\TCMatch.ahk
#include %A_ScriptDir%\lib\Eval.ahk
#include %A_ScriptDir%\lib\JSON.ahk
#include %A_ScriptDir%\Functions.ahk
; 用户自定义命令
#include *i %A_ScriptDir%\UserFunctions.ahk


apply x86 binary

apply x86 binary

; Macro Start Point

ACTIVE_ID:="BlueStacks App Player"
GUI_TITLE:="MC_AUTO Ver 1.0"

; System Variable
SysGet, IntWinCapHeight, 4 ; ĸHeight
SysGet, IntWinBorderWidth, 32 ; Width
SysGet, IntWinBorderHeight, 33 ; Height

;~ Status
BoolStarted:=false
BoolPaused:=false
BoolWantToStop:=false

BoolReSized := false
BooleanDebugMode:=false

;~ MsgBox, %DEFAULT_WIDTH% %DEFAULT_HEIGHT% "DEFAULT"
;~WinGetPos, , , winW, winH, %ACTIVE_ID%
DEFAULT_WIDTH:=966
DEFAULT_HEIGHT:=628
RUN_WIDTH:=644
RUN_HEIGHT:=428

gosub INIT_GLOBAL_VARIABLES

mainConfig := new IniController( A_ScriptDir "\Config\main.ini" )

gosub INIT_GUI

fPrintTitle("  ")
fPrintStatus("ũΰ ")
fPrintResult( "ũΰ  Ǿϴ." )
setUpBeforeStart()
return

ũν:
{
	fPrintStatus("ũ  մϴ.")
	setUpBeforeStart()
	if( BoolStarted = false ){
      BoolStarted:= true
      funcChangeGuiStatus()
		fPrintTitle("")
		goto, ũMAIN
	}
	return
}
ũ:
{
   fPrintTitle("ũ")
	fPrintStatus("ũθ մϴ.")
	fPrintResult("ũ ")
	BoolStarted:=false
	BoolWantToStop:=false

	funcChangeGuiStatus()

	exit
}
ũθε:
{
	WinActivate Mc_auto.ahk
	Send, ^s
	Reload
	return
}

checkExit(){
	global BoolWantToStop
	if ( BoolWantToStop = true ){
		gosub ũ
	}
}

#if WinActive( GUI_TITLE )
Enter::  send {tab 4}{space}+{tab 4}
NumPadEnter::  send {tab 4}{space}+{tab 4}
#if

#include %A_ScriptDir%\Scripts\GUI\Mc_auto_Gui.ahk
#include Scripts\GUI\GUI_action.ahk
#Include Scripts\1.Function_Macro.ahk
#Include Scripts\1.Launch_Macro.ahk
#Include Scripts\2.Function_Game.ahk
#Include Scripts\2.Launch_Game.ahk

#Include Scripts\3.SearchPosition.ahk
#Include Scripts\4.Mode_CASTLEBATTLE.ahk
#Include Scripts\4.Mode_Raid.ahk
#Include Scripts\4.Mode_Advanture.ahk

#Include Scripts\4.Mode_FullItem.ahk
#Include Scripts\4.Mode_HasNoKey.ahk
#Include Scripts\4.Mode_ReceivePost.ahk
#Include Scripts\4.Mode_BattlePassive.ahk
#Include Scripts\4.Mode_BattleField.ahk
#Include Scripts\4.Mode_GoldRoom.ahk
#Include Scripts\4.Mode_MonsterLevelupCheck.ahk
#Include Scripts\5.Util_PushBullet.ahk
#Include Scripts\5.Util_ScreenShot.ahk
#Include Scripts\6.TestPoint.ahk
#Include Scripts\MC_LIBRARY.ahk

#include %A_ScriptDir%\Scripts\GUI\GUI_BOTTOM_CONTROL.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_MAIN.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_TAB2_ADVANTURE.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_TAB3_CASTLEBATTLE.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_TAB4_ETC.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_Config.ahk

; Macro Start Point

ACTIVE_ID:="BlueStacks App Player"
GUI_TITLE:="MC_AUTO Ver 1.0"

; System Variable
SysGet, IntWinCapHeight, 4 ; ĸHeight
SysGet, IntWinBorderWidth, 32 ; Width
SysGet, IntWinBorderHeight, 33 ; Height

;~ Status
BoolStarted:=false
BoolPaused:=false
BoolWantToStop:=false

BoolReSized := false
BooleanDebugMode:=false

;~ MsgBox, %DEFAULT_WIDTH% %DEFAULT_HEIGHT% "DEFAULT"
;~WinGetPos, , , winW, winH, %ACTIVE_ID%
DEFAULT_WIDTH:=966
DEFAULT_HEIGHT:=628
RUN_WIDTH:=644
RUN_HEIGHT:=428

gosub INIT_GLOBAL_VARIABLES

mainConfig := new IniController( A_ScriptDir "\Config\main.ini" )

gosub INIT_GUI

fPrintTitle("  ")
fPrintStatus("ũΰ ")
fPrintResult( "ũΰ  Ǿϴ." )
setUpBeforeStart()
return

ũν:
{
	fPrintStatus("ũ  մϴ.")
	setUpBeforeStart()
	if( BoolStarted = false ){
      BoolStarted:= true
      funcChangeGuiStatus()
		fPrintTitle("")
		goto, ũMAIN
	}
	return
}
ũ:
{
   fPrintTitle("ũ")
	fPrintStatus("ũθ մϴ.")
	fPrintResult("ũ ")
	BoolStarted:=false
	BoolWantToStop:=false

	funcChangeGuiStatus()

	exit
}
ũθε:
{
	WinActivate Mc_auto.ahk
	Send, ^s
	Reload
	return
}

checkExit(){
	global BoolWantToStop
	if ( BoolWantToStop = true ){
		gosub ũ
	}
}

#if WinActive( GUI_TITLE )
Enter::  send {tab 4}{space}+{tab 4}
NumPadEnter::  send {tab 4}{space}+{tab 4}
#if

#include %A_ScriptDir%\Scripts\GUI\Mc_auto_Gui.ahk
#include Scripts\GUI\GUI_action.ahk
#Include Scripts\1.Function_Macro.ahk
#Include Scripts\1.Launch_Macro.ahk
#Include Scripts\2.Function_Game.ahk
#Include Scripts\2.Launch_Game.ahk

#Include Scripts\3.SearchPosition.ahk
#Include Scripts\4.Mode_CASTLEBATTLE.ahk
#Include Scripts\4.Mode_Raid.ahk
#Include Scripts\4.Mode_Advanture.ahk
#Include Scripts\4.Mode_HasNoKey.ahk
#Include Scripts\4.Mode_BattlePassive.ahk
#Include Scripts\4.Mode_BattleField.ahk
#Include Scripts\4.Mode_GoldRoom.ahk
#Include Scripts\4.Mode_MonsterLevelupCheck.ahk
#Include Scripts\5.Util_PushBullet.ahk
#Include Scripts\5.Util_ScreenShot.ahk
#Include Scripts\6.TestPoint.ahk
#Include Scripts\MC_LIBRARY.ahk

#include %A_ScriptDir%\Scripts\GUI\GUI_BOTTOM_CONTROL.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_MAIN.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_TAB2_ADVANTURE.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_TAB3_CASTLEBATTLE.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_TAB4_ETC.ahk
#include %A_ScriptDir%\Scripts\GUI\GUI_Config.ahk


Fix VimDConfig_plugin

Fix VimDConfig_plugin

VimDConfig:
    vim.SetPlugin("VimDConfig", "Array", "0.1", "VimDesktop的配置界面")
    vim.SetAction("<VimDConfig_Plugin>", "显示 VimDesktop 插件信息")
    vim.SetAction("<VimDConfig_Keymap>", "显示 VimDesktop 热键信息")
    vim.SetAction("<VimDConfig_EditConfig>", "打开 VimDesktop 配置文件")
return

<VimDConfig_Plugin>:
    GUI, VimDConfig_plugin:Destroy
    GUI, VimDConfig_plugin:Default
    GUI, VimDConfig_plugin:Font, s10, Microsoft YaHei

    GUI, VimDConfig_plugin:Add, GroupBox, x10 y460 w170 h70, 过滤 &F
    GUI, VimDConfig_plugin:Add, Edit, x20 y490 gsearch_plugin v_search

    GUI, VimDConfig_plugin:Add, GroupBox, x190 y10 w650 h520, 动作 &A
    GUI, VimDConfig_plugin:Add, ListView, glistview x200 y35 w630 h482 grid altsubmit, 序号|动作|描述（双击进入文件）

    LV_ModifyCol(1, "center")
    LV_ModifyCol(2, "left 250")
    LV_ModifyCol(3, "left 320")

    ; 先创建右边的 ListView，再创建左边的 ListView，否则 LV_Modify 时会出问题。
    GUI, VimDConfig_plugin:Add, GroupBox, x10 y10 w170 h440, 插件 &P
    GUI, VimDConfig_plugin:Add, ListView, x20 y35 w150 h400 grid altsubmit gVimDConfig_LoadActions, 名称

    for plugin, obj in vim.PluginList
        LV_Add("", plugin)

    LV_Modify(1, "Select")

    GUI, VimDConfig_plugin:Show
    ControlFocus, Edit1, A
return

<VimDConfig_Keymap>:
    menu, VimDConfig_keymap_menu, add
    menu, VimDConfig_keymap_menu, add, &Exit, VimDConfig_keymap_exit

    GUI, VimDConfig_keymap:Destroy
    GUI, VimDConfig_keymap:Default
    GUI, VimDConfig_keymap:Font, s10, Microsoft YaHei

    GUI, VimDConfig_keymap:Add, GroupBox, x10 y10 w200 h269, 插件 &P
    GUI, VimDConfig_keymap:Add, ListBox, x20 y35 w180 R12 center gVimDConfig_keymap_loadmodelist

    GUI, VimDConfig_keymap:Add, GroupBox, x10 y290 w200 h135, 模式 &M
    GUI, VimDConfig_keymap:Add, ListBox, x20 y315 w180 R5 center gVimDConfig_keymap_loadhotkey

    GUI, VimDConfig_keymap:Add, GroupBox, x10 y435 w200 h61, 过滤 &F
    GUI, VimDConfig_keymap:Add, Edit, gsearch_keymap v_search x20 y460 w180 h25

    GUI, VimDConfig_keymap:Add, GroupBox, x225 y10 w650 h486, 映射 &K
    GUI, VimDConfig_keymap:Add, Listview, glistview x235 y36 w630 h450 grid, 热键|动作（双击定位，右键双击编辑）|描述

    LV_ModifyCol(1, "left 100")
    LV_ModifyCol(2, "left 250")
    LV_ModifyCol(3, "left 259")

    VimDConfig_keymap_loadwinlist()
    VimDConfig_keymap_loadhotkey(VimDConfig_keymap_loadmodelist(thiswin))

    GUI, VimDConfig_keymap:Show
    ControlFocus, Edit1, A
return

<VimDConfig_EditConfig>:
    Run, %A_ScriptDir%\vimd.ini
return

VimDConfig_LoadActions:
    If A_GuiEvent = I
    {
        if not InStr(ErrorLevel, "S", true)
        {
            return
        }

        GUI, VimDConfig_plugin:ListView, sysListview322
        LV_GetText(plugin, A_EventInfo)
        GUI, VimDConfig_plugin:Default
        GUI, VimDConfig_plugin:ListView, sysListview321
        idx := 1
        LV_Delete()

        global current_plugin := ""
        for action, type in vim.ActionFromPlugin
        {
            If type = %plugin%
            {
                Desc := vim.GetAction(action)
                LV_Add("", idx, action, Desc.Comment)
                current_plugin .= idx "`t" action "`t" Desc.Comment "`n"
                idx++
            }
        }
    }
return

VimDConfig_keymap_exit:
{
    GUI, VimDConfig_keymap:Destroy
    return
}

VimDConfig_keymap_loadwinlist()
{
    global vim
    list := "|全局"
    GUI, VimDConfig_keymap:Default
    for win, obj in vim.WinList
    {
        if vim.ExcludeWinList[win]
        {
            continue
        }

        ; Convert class name TTOTAL_CMD to plugin name TotalCommander
        if (win = "TTOTAL_CMD")
        {
            win := "TotalCommander"
        }
        list .= "|" win
    }
    GuiControl, , ListBox1, %list%
}

VimDConfig_keymap_loadmodelist:
    VimDConfig_keymap_loadmodelist()
    GUI, VimDConfig_keymap:Default
    LV_delete()
    GuiControl, Choose, ListBox2, |normal
return

VimDConfig_keymap_loadmodelist(win = "")
{
    global vim
    GUI, VimDConfig_keymap:Default
    If not strlen(win)
        ControlGet, win, Choice, , ListBox1
    If win = 全局
        winObj := vim.GetWin()
    Else
        winObj := vim.GetWin(win)
    for mode, obj in winObj.modeList
        mlist .= "|" mode
    GuiControl, , ListBox2, %mlist%
    return win
}

VimDConfig_keymap_loadhotkey:
    GUI, VimDConfig_keymap:Default
    ControlGet, win, Choice, , ListBox1
    win := RegExMatch(win, "^全局$") ? "" : win

    ; Convert plugin name TotalCommander to class name TTOTAL_CMD
    if (win = "TotalCommander")
    {
        win := "TTOTAL_CMD"
    }

    ControlGet, mode, Choice, , ListBox2
    VimDConfig_keymap_loadhotkey(win, mode)
return

VimDConfig_keymap_loadhotkey(win, mode = "")
{
    global vim
    global current_keymap := ""
    If strlen(mode)
    {
        winObj  := vim.GetWin(win)
        modeobj := winObj.modeList[mode]
    }
    Else
        modeobj := vim.GetMode(win)
    GUI, VimDConfig_keymap:Default
    LV_delete()
    for key, i in modeobj.keymapList
    {
        ; Type = 1 : Function
        if (vim.GetAction(i).Type = 1)
        {
            ActionDescList := vim.GetAction(i).Comment
            actionDesc := StrSplit(%ActionDescList%[key], "|")
            LV_ADD("", Key, actionDesc[1], actionDesc[2])
            current_keymap .= Key "`t" actionDesc[1] "`t" actionDesc[2] "`n"
        }
        else
        {
            LV_Add("", RegExReplace(Key, "<S-(.*)>", "$1"), i, vim.GetAction(i).Comment)
            current_keymap .= Key "`t" i "`t" vim.GetAction(i).Comment "`n"
        }
    }
}

listview:
    if A_GuiEvent = DoubleClick
    {
        ;~ ToolTip You double-clicked row number %A_EventInfo%.
        LV_GetText(SelectedAction, A_EventInfo, 2)
        LV_GetText(SelectedDesc, A_EventInfo, 3)
        SearchFileForEdit(SelectedAction, SelectedDesc, false)
    }
    else if A_GuiEvent = R
    {
        LV_GetText(SelectedAction, A_EventInfo, 2)
        LV_GetText(SelectedDesc, A_EventInfo, 3)
        SearchFileForEdit(SelectedAction, SelectedDesc, true)
    }

return

SearchFileForEdit(Action, Desc, EditKeyMapping)
{
    IsUserCmd := RegExMatch(Action, "^(run|key|dir|tccmd|wshkey)$")
    if (IsUserCmd || EditKeyMapping)
    {
        SearchLine := "=" Action
        if (IsUserCmd || Action == "function")
        {
            SearchLine := Action "|" Desc
        }

        Loop, Read, %A_ScriptDir%\vimd.ini
        {
            if (InStr(A_LoopReadLine, SearchLine))
            {
                EditFile(A_ScriptDir "\vimd.ini", A_Index)
                return
            }
        }

        EditFile(A_ScriptDir "\vimd.ini")
        return
    }

    label := Action ":"
    if (Action == "function")
    {
        label := Desc
    }

    Loop, %A_ScriptDir%\plugins\*.ahk, , 1
    {
        Loop, Read, %A_LoopFileFullPath%
        {
            if (InStr(A_LoopReadLine, label) == 1)
            {
                EditFile(A_LoopFileFullPath, A_Index)
                return
            }
        }
    }

    Loop, %A_ScriptDir%\core\*.ahk, , 1
    {
        Loop, Read, %A_LoopFileFullPath%
        {
            if (InStr(A_LoopReadLine, label) = 1)
            {
                EditFile(A_LoopFileFullPath, A_Index)
                return
            }
        }
    }
}

EditFile(editPath, line := 1)
{
    editorArgs := {}
    editorArgs["notepad"] := "/g $line $file"
    editorArgs["notepad2"] := "/g $line $file"
    editorArgs["sublime_text"] := "$file:$line"
    editorArgs["vim"] := "+$line $file"
    editorArgs["gvim"] := "--remote-silent-tab +$line $file"
    editorArgs["everedit"] := "-n$line $file"
    editorArgs["notepad++"] := "-n$line $file"
    editorArgs["EmEditor"] := "-l $line $file"
    editorArgs["uedit32"] := "$file/$line"
    editorArgs["Editplus"] := "$file -cursor $line"
    editorArgs["textpad"] := "$file($line)"
    editorArgs["pspad"] := "$file /$line"
    editorArgs["ConTEXT"] := "$file /g1:$line"
    editorArgs["scite"] := "$file -goto:$line"

    Global editor

    If not FileExist(editor)
    {
        MsgBox, 请配置 vimd.ini 中 [config] 中的 editor ，并重启 vimd ！
        return
    }

    ; 根据编辑器 exe 名称获取打开参数
    SplitPath, editor, , , OutExtension, OutNameNoExt
    args := editorArgs[OutNameNoExt]
    StringReplace, args, args, $line, %line%
    StringReplace, args, args, $file, "%editPath%"
    target := editor " " args
    if (OutExtension = "sh")
    {
        target := "sh.exe " target
    }

    run, %target%
}

search_keymap:
    global current_keymap
    search_to_display(current_keymap)
return

search_plugin:
    global current_plugin
    search_to_display(current_plugin)
return

search_to_display(lines)
{
    Gui Submit, nohide
    GuiControlGet, OutputVar, , _search

    text := StrSplit(lines, "`n")

    LV_Delete() ; 清理不掉，第二次加载后，都成了重复的了，不知道怎么处理
    GuiControl, -Redraw, listview ; 重新启用重绘 (上面把它禁用了)
    for k, v in text
    {
        if v =
            continue
        if Instr(v, OutputVar)
        {
            list := StrSplit(v, "`t")
            LV_Add("", list[1], list[2], list[3])
        }
    }
    GuiControl, +Redraw, listview ; 重新启用重绘 (上面把它禁用了)
}

VimDConfig:
    vim.SetPlugin("VimDConfig", "Array", "0.1", "VimDesktop的配置界面")
    vim.SetAction("<VimDConfig_Plugin>", "显示 VimDesktop 插件信息")
    vim.SetAction("<VimDConfig_Keymap>", "显示 VimDesktop 热键信息")
    vim.SetAction("<VimDConfig_EditConfig>", "打开 VimDesktop 配置文件")
return

<VimDConfig_Plugin>:
    GUI, VimDConfig_plugin:Destroy
    GUI, VimDConfig_plugin:Default
    GUI, VimDConfig_plugin:Font, s10, Microsoft YaHei

    GUI, VimDConfig_plugin:Add, GroupBox, x10 y10 w170 h440, 插件 &P
    GUI, VimDConfig_plugin:Add, ListView, x20 y35 w150 h400 grid altsubmit gVimDConfig_LoadActions, 名称
    firstPlugin := true
    for plugin, obj in vim.PluginList
    {
        if (firstPlugin)
        {
            LV_Add("Select", plugin)
            firstPlugin := false
        }
        else
        {
            LV_Add("", plugin)
        }
    }

    GUI, VimDConfig_plugin:Add, GroupBox, x10 y460 w170 h70, 过滤 &F
    GUI, VimDConfig_plugin:Add, Edit, x20 y490 gsearch_plugin v_search

    GUI, VimDConfig_plugin:Add, GroupBox, x190 y10 w650 h520, 动作 &A
    GUI, VimDConfig_plugin:Add, ListView, glistview x200 y35 w630 h482 grid altsubmit, 序号|动作|描述（双击进入文件）

    LV_ModifyCol(1, "center")
    LV_ModifyCol(2, "left 250")
    LV_ModifyCol(3, "left 320")
    GUI, VimDConfig_plugin:Show
    ControlFocus, Edit1, A
return

<VimDConfig_Keymap>:
    menu, VimDConfig_keymap_menu, add
    menu, VimDConfig_keymap_menu, add, &Exit, VimDConfig_keymap_exit

    GUI, VimDConfig_keymap:Destroy
    GUI, VimDConfig_keymap:Default
    GUI, VimDConfig_keymap:Font, s10, Microsoft YaHei

    GUI, VimDConfig_keymap:Add, GroupBox, x10 y10 w200 h269, 插件 &P
    GUI, VimDConfig_keymap:Add, ListBox, x20 y35 w180 R12 center gVimDConfig_keymap_loadmodelist

    GUI, VimDConfig_keymap:Add, GroupBox, x10 y290 w200 h135, 模式 &M
    GUI, VimDConfig_keymap:Add, ListBox, x20 y315 w180 R5 center gVimDConfig_keymap_loadhotkey

    GUI, VimDConfig_keymap:Add, GroupBox, x10 y435 w200 h61, 过滤 &F
    GUI, VimDConfig_keymap:Add, Edit, gsearch_keymap v_search x20 y460 w180 h25

    GUI, VimDConfig_keymap:Add, GroupBox, x225 y10 w650 h486, 映射 &K
    GUI, VimDConfig_keymap:Add, Listview, glistview x235 y36 w630 h450 grid, 热键|动作（双击定位，右键双击编辑）|描述

    LV_ModifyCol(1, "left 100")
    LV_ModifyCol(2, "left 250")
    LV_ModifyCol(3, "left 259")

    VimDConfig_keymap_loadwinlist()
    VimDConfig_keymap_loadhotkey(VimDConfig_keymap_loadmodelist(thiswin))

    GUI, VimDConfig_keymap:Show
    ControlFocus, Edit1, A
return

<VimDConfig_EditConfig>:
    Run, %A_ScriptDir%\vimd.ini
return

VimDConfig_LoadActions:
    If A_GuiEvent = I
    {
        if not InStr(ErrorLevel, "S", true)
        {
            return
        }

        GUI, VimDConfig_plugin:ListView, sysListview321
        LV_GetText(plugin, A_EventInfo)
        GUI, VimDConfig_plugin:Default
        GUI, VimDConfig_plugin:ListView, sysListview322
        idx := 1
        LV_Delete()

        global current_plugin := ""
        for action, type in vim.ActionFromPlugin
        {
            If type = %plugin%
            {
                Desc := vim.GetAction(action)
                LV_Add("", idx, action, Desc.Comment)
                current_plugin .= idx "`t" action "`t" Desc.Comment "`n"
                idx++
            }
        }
    }
return

VimDConfig_keymap_exit:
{
    GUI, VimDConfig_keymap:Destroy
    return
}

VimDConfig_keymap_loadwinlist()
{
    global vim
    list := "|全局"
    GUI, VimDConfig_keymap:Default
    for win, obj in vim.WinList
    {
        if vim.ExcludeWinList[win]
        {
            continue
        }

        ; Convert class name TTOTAL_CMD to plugin name TotalCommander
        if (win = "TTOTAL_CMD")
        {
            win := "TotalCommander"
        }
        list .= "|" win
    }
    GuiControl, , ListBox1, %list%
}

VimDConfig_keymap_loadmodelist:
    VimDConfig_keymap_loadmodelist()
    GUI, VimDConfig_keymap:Default
    LV_delete()
    GuiControl, Choose, ListBox2, |normal
return

VimDConfig_keymap_loadmodelist(win = "")
{
    global vim
    GUI, VimDConfig_keymap:Default
    If not strlen(win)
        ControlGet, win, Choice, , ListBox1
    If win = 全局
        winObj := vim.GetWin()
    Else
        winObj := vim.GetWin(win)
    for mode, obj in winObj.modeList
        mlist .= "|" mode
    GuiControl, , ListBox2, %mlist%
    return win
}

VimDConfig_keymap_loadhotkey:
    GUI, VimDConfig_keymap:Default
    ControlGet, win, Choice, , ListBox1
    win := RegExMatch(win, "^全局$") ? "" : win

    ; Convert plugin name TotalCommander to class name TTOTAL_CMD
    if (win = "TotalCommander")
    {
        win := "TTOTAL_CMD"
    }

    ControlGet, mode, Choice, , ListBox2
    VimDConfig_keymap_loadhotkey(win, mode)
return

VimDConfig_keymap_loadhotkey(win, mode = "")
{
    global vim
    global current_keymap := ""
    If strlen(mode)
    {
        winObj  := vim.GetWin(win)
        modeobj := winObj.modeList[mode]
    }
    Else
        modeobj := vim.GetMode(win)
    GUI, VimDConfig_keymap:Default
    LV_delete()
    for key, i in modeobj.keymapList
    {
        ; Type = 1 : Function
        if (vim.GetAction(i).Type = 1)
        {
            ActionDescList := vim.GetAction(i).Comment
            actionDesc := StrSplit(%ActionDescList%[key], "|")
            LV_ADD("", Key, actionDesc[1], actionDesc[2])
            current_keymap .= Key "`t" actionDesc[1] "`t" actionDesc[2] "`n"
        }
        else
        {
            LV_Add("", RegExReplace(Key, "<S-(.*)>", "$1"), i, vim.GetAction(i).Comment)
            current_keymap .= Key "`t" i "`t" vim.GetAction(i).Comment "`n"
        }
    }
}

listview:
    if A_GuiEvent = DoubleClick
    {
        ;~ ToolTip You double-clicked row number %A_EventInfo%.
        LV_GetText(SelectedAction, A_EventInfo, 2)
        LV_GetText(SelectedDesc, A_EventInfo, 3)
        SearchFileForEdit(SelectedAction, SelectedDesc, false)
    }
    else if A_GuiEvent = R
    {
        LV_GetText(SelectedAction, A_EventInfo, 2)
        LV_GetText(SelectedDesc, A_EventInfo, 3)
        SearchFileForEdit(SelectedAction, SelectedDesc, true)
    }

return

SearchFileForEdit(Action, Desc, EditKeyMapping)
{
    IsUserCmd := RegExMatch(Action, "^(run|key|dir|tccmd|wshkey)$")
    if (IsUserCmd || EditKeyMapping)
    {
        SearchLine := "=" Action
        if (IsUserCmd || Action == "function")
        {
            SearchLine := Action "|" Desc
        }

        Loop, Read, %A_ScriptDir%\vimd.ini
        {
            if (InStr(A_LoopReadLine, SearchLine))
            {
                EditFile(A_ScriptDir "\vimd.ini", A_Index)
                return
            }
        }

        EditFile(A_ScriptDir "\vimd.ini")
        return
    }

    label := Action ":"
    if (Action == "function")
    {
        label := Desc
    }

    Loop, %A_ScriptDir%\plugins\*.ahk, , 1
    {
        Loop, Read, %A_LoopFileFullPath%
        {
            if (InStr(A_LoopReadLine, label) == 1)
            {
                EditFile(A_LoopFileFullPath, A_Index)
                return
            }
        }
    }

    Loop, %A_ScriptDir%\core\*.ahk, , 1
    {
        Loop, Read, %A_LoopFileFullPath%
        {
            if (InStr(A_LoopReadLine, label) = 1)
            {
                EditFile(A_LoopFileFullPath, A_Index)
                return
            }
        }
    }
}

EditFile(editPath, line := 1)
{
    editorArgs := {}
    editorArgs["notepad"] := "/g $line $file"
    editorArgs["notepad2"] := "/g $line $file"
    editorArgs["sublime_text"] := "$file:$line"
    editorArgs["vim"] := "+$line $file"
    editorArgs["gvim"] := "--remote-silent-tab +$line $file"
    editorArgs["everedit"] := "-n$line $file"
    editorArgs["notepad++"] := "-n$line $file"
    editorArgs["EmEditor"] := "-l $line $file"
    editorArgs["uedit32"] := "$file/$line"
    editorArgs["Editplus"] := "$file -cursor $line"
    editorArgs["textpad"] := "$file($line)"
    editorArgs["pspad"] := "$file /$line"
    editorArgs["ConTEXT"] := "$file /g1:$line"
    editorArgs["scite"] := "$file -goto:$line"

    Global editor

    If not FileExist(editor)
    {
        MsgBox, 请配置 vimd.ini 中 [config] 中的 editor ，并重启 vimd ！
        return
    }

    ; 根据编辑器 exe 名称获取打开参数
    SplitPath, editor, , , OutExtension, OutNameNoExt
    args := editorArgs[OutNameNoExt]
    StringReplace, args, args, $line, %line%
    StringReplace, args, args, $file, "%editPath%"
    target := editor " " args
    if (OutExtension = "sh")
    {
        target := "sh.exe " target
    }

    run, %target%
}

search_keymap:
    global current_keymap
    search_to_display(current_keymap)
return

search_plugin:
    global current_plugin
    search_to_display(current_plugin)
return

search_to_display(lines)
{
    Gui Submit, nohide
    GuiControlGet, OutputVar, , _search

    text := StrSplit(lines, "`n")

    LV_Delete() ; 清理不掉，第二次加载后，都成了重复的了，不知道怎么处理
    GuiControl, -Redraw, listview ; 重新启用重绘 (上面把它禁用了)
    for k, v in text
    {
        if v =
            continue
        if Instr(v, OutputVar)
        {
            list := StrSplit(v, "`t")
            LV_Add("", list[1], list[2], list[3])
        }
    }
    GuiControl, +Redraw, listview ; 重新启用重绘 (上面把它禁用了)
}


tweak windows autohotkey settings

tweak windows autohotkey settings

^Tab::
Send #{Tab}
return

^!`::
IfWinActive, ahk_class TMobaXtermForm
    Send !{Tab}
else
    WinActivate ahk_class TMobaXtermForm
return

^`::
IfWinActive, ahk_exe mintty.exe
    Send !{Tab}
else
    WinActivate ahk_exe mintty.exe
return

^!c::
IfWinActive, ahk_exe chrome.exe
    Send !{Tab}
else
    WinActivate ahk_exe chrome.exe
return

^!f::
IfWinActive, ahk_exe firefox.exe
    Send !{Tab}
else
    WinActivate ahk_exe firefox.exe
return

^!u::
IfWinActive, ahk_exe Unity.exe
    Send !{Tab}
else
    WinActivate ahk_exe Unity.exe
return

^!a::
IfWinActive, ahk_exe atom.exe
    Send !{Tab}
else
    WinActivate ahk_exe atom.exe
return

^!v::
IfWinActive, ahk_exe gvim.exe
    Send !{Tab}
else
    WinActivate ahk_exe gvim.exe
return

^!x::
IfWinActive, ahk_exe devenv.exe
    Send !{Tab}
else
    WinActivate ahk_exe devenv.exe
return

^!s::
IfWinActive, ahk_exe ApplicationFrameHost.exe
    Send !{Tab}
else
    WinActivate ahk_exe ApplicationFrameHost.exe
return

^!i::
IfWinActive, ahk_exe idea.exe
    Send !{Tab}
else
    WinActivate ahk_exe idea.exe
return

^!t::
IfWinActive, ahk_exe Telegram.exe
    Send !{Tab}
else
    WinActivate ahk_exe Telegram.exe
return

^!h::
IfWinActive, ahk_exe zeal.exe
    Send !{Tab}
else
    WinActivate ahk_exe zeal.exe
return

^!m::
IfWinActive, ahk_exe cloudmusic.exe
    Send !{Tab}
else
    WinActivate ahk_exe cloudmusic.exe
return

^!e::
IfWinActive, ahk_exe Evernote.exe
    Send !{Tab}
else
    WinActivate ahk_exe Evernote.exe
return

^!p::
IfWinActive, ahk_exe xmind.exe
    Send !{Tab}
else
    WinActivate ahk_exe xmind.exe
return

^!Space::
Process,close,explorer.exe
sleep, 50 ;This sleep 5000 is to let you see what actually happens. Decrease it later
run, explorer.exe
WinWait, ahk_class CabinetWClass
WinClose ;close the new explorer window
return

^Tab::
Send #{Tab}
return

^`::
IfWinActive, ahk_class TMobaXtermForm
    Send !{Tab}
else
    WinActivate ahk_class TMobaXtermForm
return

^!`::
IfWinActive, ahk_exe mintty.exe
    Send !{Tab}
else
    WinActivate ahk_exe mintty.exe
return

^!c::
IfWinActive, ahk_exe chrome.exe
    Send !{Tab}
else
    WinActivate ahk_exe chrome.exe
return

^!f::
IfWinActive, ahk_exe firefox.exe
    Send !{Tab}
else
    WinActivate ahk_exe firefox.exe
return

^!u::
IfWinActive, ahk_exe Unity.exe
    Send !{Tab}
else
    WinActivate ahk_exe Unity.exe
return

^!a::
IfWinActive, ahk_exe atom.exe
    Send !{Tab}
else
    WinActivate ahk_exe atom.exe
return

^!v::
IfWinActive, ahk_exe gvim.exe
    Send !{Tab}
else
    WinActivate ahk_exe gvim.exe
return

^!x::
IfWinActive, ahk_exe devenv.exe
    Send !{Tab}
else
    WinActivate ahk_exe devenv.exe
return

^!s::
IfWinActive, ahk_exe ApplicationFrameHost.exe
    Send !{Tab}
else
    WinActivate ahk_exe ApplicationFrameHost.exe
return

^!i::
IfWinActive, ahk_exe idea.exe
    Send !{Tab}
else
    WinActivate ahk_exe idea.exe
return

^!t::
IfWinActive, ahk_exe Telegram.exe
    Send !{Tab}
else
    WinActivate ahk_exe Telegram.exe
return

^!h::
IfWinActive, ahk_exe zeal.exe
    Send !{Tab}
else
    WinActivate ahk_exe zeal.exe
return

^!m::
IfWinActive, ahk_exe cloudmusic.exe
    Send !{Tab}
else
    WinActivate ahk_exe cloudmusic.exe
return

^!e::
IfWinActive, ahk_exe Evernote.exe
    Send !{Tab}
else
    WinActivate ahk_exe Evernote.exe
return

^!p::
IfWinActive, ahk_exe xmind.exe
    Send !{Tab}
else
    WinActivate ahk_exe xmind.exe
return

^!Space::
Process,close,explorer.exe
sleep, 50 ;This sleep 5000 is to let you see what actually happens. Decrease it later
run, explorer.exe
WinWait, ahk_class CabinetWClass
WinClose ;close the new explorer window
return


Add path onto which to store this file

Add path onto which to store this file

; Put this file in
; %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup

FileEncoding, UTF-8 ; This file needs to be saved/encoded with "UTF-8 with BOM"

; Use Swedish characters on US-English keyboard
![:: Send, å
!+{:: Send, Å
!':: Send, ä
!+':: Send, Ä
!;:: Send, ö
!+;:: Send, Ö

; HHKB settings to mimic macOS behavior on Windows
LWin::LCtrl  ; this one is better to use SharpKeys for, as it is unreliable here
<^Right:: Send, {End}
<^Left:: Send, {Home}
<^Up:: Send, {PgUp}
<^Down:: Send, {PgDn}
<+^Right:: Send, {LShift down}{End}{LShift up}
<+^Left:: Send, {LShift down}{Home}{LShift up}
<+^Up:: Send, {LShift down}{PgUp}{LShift up}
<+^Down:: Send, {LShift down}{PgDn}{LShift up}

; Windows laptop
AppsKey:: Send, {RWin}


DC 插件：<DC_CreateFileShortcut> 添加当前路径信息

DC 插件：<DC_CreateFileShortcut> 添加当前路径信息

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"
    DC_Run("cm_MarkUnmarkAll")

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

    DC_Run("cm_EditComment")
    Send, {F2}

    SelectedFiles := ""
    Result := ""
return

<DC_UnMarkFile>:
    DescriptPath := DC_RunGet("cm_CopyCurrentPathToClip") . "\descript.ion"
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    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
    }

    Sleep, 20

    DC_Run("cm_EditComment")
    Send, {F2}

    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

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"
    DC_Run("cm_MarkUnmarkAll")

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

    DC_Run("cm_EditComment")
    Send, {F2}

    SelectedFiles := ""
    Result := ""
return

<DC_UnMarkFile>:
    DescriptPath := DC_RunGet("cm_CopyCurrentPathToClip") . "\descript.ion"
    SelectedFiles := DC_RunGet("cm_CopyNamesToClip")
    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
    }

    Sleep, 20

    DC_Run("cm_EditComment")
    Send, {F2}

    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"
    } else if (OutVar != "") {
        FileCreateShortcut, % FilePath, % RegExReplace(FilePath, "\.[^.]*$", ".lnk")
    }
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