zs 입력시 좀 더 확실하게 maximize 가 될 수 있도록 수정.

zs 입력시 좀 더 확실하게 maximize 가 될 수 있도록 수정.

/*
  key mapping functions : key_[a-z]+
  @Author : johngrib82@gmail.com
  @Created : 2015. NOV. 26
*/

/*
  <START> 2 char commands -----------------
*/
/*
  to upper case , to lower case
*/
key_gu(ByRef input_number){

  old := ClipboardAll
  Clipboard := ""
  Send, ^c

  ClipWait 0.5
  if (ErrorLevel){
    Clipboard := old
    return
  }

  if( GetKeyState("Shift") )
    StringUpper, Clipboard, Clipboard
  else
    StringLower, Clipboard, Clipboard

  Send, ^v
  Clipboard := old
  return
}
/*
  tab move
  gt : next tab
  gr : previous tab
*/
key_gt(ByRef input_number) {
  Send, ^{PGDN %input_number%}
}
key_gr(ByRef input_number) {
  Send, ^{PGUP %input_number%}
}

/*
  move mouse cursor to edge of activaed window
  gq  gw  ge
  ga  gs  gd
  gz  gx  gc
*/
key_gq(ByRef input_number){
  MouseMove, 2, 0
}
key_gw(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww/2, 0
}
key_ge(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww - 2, 0
}
key_ga(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, 2, hh/2
}
key_gs(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww/2, hh/2
}
key_gd(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww - 2, hh/2
}
key_gz(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, 2, hh - 2
}
key_gx(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww/2, hh - 2
}
key_gc(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww -2, hh - 2
}

/*
  move activated window to n'th monitor location
  zq  zw  ze
  za  zs  zd
  zz  zx  zc
*/
key_zq(ByRef input_number){
  move_window(input_number, 7, "A")
}
key_zw(ByRef input_number){
  move_window(input_number, 8, "A")
}
key_ze(ByRef input_number){
  move_window(input_number, 9, "A")
}
key_za(ByRef input_number){
  move_window(input_number, 4, "A")
}
key_zs(ByRef input_number){
  move_window(input_number, 5, "A")
  WinMaximize, A
}
key_zd(ByRef input_number){
  move_window(input_number, 6, "A")
}
key_zz(ByRef input_number){
  move_window(input_number, 1, "A")
}
key_zx(ByRef input_number){
  move_window(input_number, 2, "A")
}
key_zc(ByRef input_number){
  move_window(input_number, 3, "A")
}
/*
  <END> 2 char commands -----------------
*/

/*
  Control Mouse Pointer movement By w a s d
  w : up
  a : left
  s : down
  d : right
*/
key_w(ByRef input_number) {
  if(input_number = "") {
    input_number = 1
    func_mouse_move( input_number , 1, 1, 1 )
  }
}
key_a(ByRef input_number) {
  if( GetKeyState("Shift") ) {
    func_i_o_a("a")
  } else if(input_number = "")
    input_number = 1
  func_mouse_move( 1, input_number, 1, 1 )
}
key_s(ByRef input_number) {
  if(input_number = "")
    input_number = 1
  func_mouse_move( 1, 1, input_number, 1 )
}
key_d(ByRef input_number) {
  if(input_number = "")
    input_number = 1
  func_mouse_move( 1, 1, 1, input_number )
}

/*
  q : Click Mouse Left Button
  ^q : Click Hold
  +q : unHold
*/
key_q(ByRef input_number) {
  if( GetKeyState("Control"))
    Click Down Left
  else if( GetKeyState("Shift"))
    Click Up Left
  else
    Click, Left, %input_number%
}

/*
  e : Click Mouse Right Button
  ^e : Click Hold
  +e : unHold
*/
key_e(ByRef input_number) {
  if( GetKeyState("Control") )
    Click Down Right
  else if( GetKeyState("Shift") )
    Click Up Right
  else
    Click, Right, %input_number%
}

/*
  i, o, a : mode changer
*/
key_i(ByRef input_number){
  func_i_o_a("i")
}
key_o(ByRef input_number){
  func_i_o_a("o")
}

/*
  0 : Home
  $ : End
*/
key_0(ByRef input_number) {
  Send, {Home}
}
key_4(ByRef input_number) {
  if(GetKeyState("shift", "P"))
    Send, {End}
}

/*
  p : paste
  y : copy
*/
key_p(ByRef input_number){
  Send, ^{v %input_number%}
}
key_y(ByRef input_number){
  temp := Clipboard
  Send, ^{c}
  Sleep 500

  if(input_number = ""){
    CLIP.num_unshift(Clipboard)
  } else {
    CLIP.set_value(input_number, Clipboard)
  }
  Clipboard := temp
}

/*
  f  : Mouse Wheel Down
  ^f : Page Down
*/
key_f(ByRef input_number) {
  if( GetKeyState("Control") )
    Send, {PGDN %input_number%}
  else
    MouseClick, WheelDown, , , input_number
}

/*
  r : Mouse Wheel Up
*/
key_r(ByRef input_number) {
  MouseClick, WheelUp, , , input_number
}

/*
  b  : previous word (^left)
  +b : next word (^right)
  ^b : Page Up
*/
key_b(ByRef input_number) {
  if( GetKeyState("Control") )
    Send, {PGUP %input_number%}
  else if( GetKeyState("Shift") )
    Send, ^{Right %input_number%}
  else
    Send, ^{Left %input_number%}
}

/*
  u : undo
*/
key_u(ByRef input_number){
  if(input_number <> "")
    Send, ^{z %input_number%}
}

/*
  x, +x : delete, backspace
*/
key_x(ByRef input_number){
  if(GetKeyState("Control"))
    Send, ^{x}
  else if(GetKeyState("Shift"))
    Send, {BackSpace %input_number%}
  else if(input_number <> "")
    Send, {Delete %input_number%}
}

/*
  do nothing
*/
key_c(ByRef input_number){
}
key_n(ByRef input_number){
}
key_t(ByRef input_number){
}
key_v(ByRef input_number){
  if(GetKeyState("Shift")){
    Send, {ShiftUp}
  } else {
    Send, {ShiftDown}
  }
}

/*
  H J K L move
*/
/*
key_h(ByRef input_number) {
  Send {Left %input_number%}
}
key_j(ByRef input_number) {
  Send {Down %input_number%}
}
key_k(ByRef input_number) {
  Send {Up %input_number%}
}
key_l(ByRef input_number) {
  Send {Right %input_number%}
}
*/

/*
  key mapping functions : key_[a-z]+
  @Author : johngrib82@gmail.com
  @Created : 2015. NOV. 26
*/

/*
  <START> 2 char commands -----------------
*/
/*
  to upper case , to lower case
*/
key_gu(ByRef input_number){

  old := ClipboardAll
  Clipboard := ""
  Send, ^c

  ClipWait 0.5
  if (ErrorLevel){
    Clipboard := old
    return
  }

  if( GetKeyState("Shift") )
    StringUpper, Clipboard, Clipboard
  else
    StringLower, Clipboard, Clipboard

  Send, ^v
  Clipboard := old
  return
}
/*
  tab move
  gt : next tab
  gr : previous tab
*/
key_gt(ByRef input_number) {
  Send, ^{PGDN %input_number%}
}
key_gr(ByRef input_number) {
  Send, ^{PGUP %input_number%}
}

/*
  move mouse cursor to edge of activaed window
  gq  gw  ge
  ga  gs  gd
  gz  gx  gc
*/
key_gq(ByRef input_number){
  MouseMove, 2, 0
}
key_gw(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww/2, 0
}
key_ge(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww - 2, 0
}
key_ga(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, 2, hh/2
}
key_gs(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww/2, hh/2
}
key_gd(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww - 2, hh/2
}
key_gz(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, 2, hh - 2
}
key_gx(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww/2, hh - 2
}
key_gc(ByRef input_number){
  WinGet, winid ,, A
  WinGetActiveStats, winid, ww, hh, xx, yy
  MouseMove, ww -2, hh - 2
}

/*
  move activated window to n'th monitor location
  zq  zw  ze
  za  zs  zd
  zz  zx  zc
*/
key_zq(ByRef input_number){
  move_window(input_number, 7, "A")
}
key_zw(ByRef input_number){
  move_window(input_number, 8, "A")
}
key_ze(ByRef input_number){
  move_window(input_number, 9, "A")
}
key_za(ByRef input_number){
  move_window(input_number, 4, "A")
}
key_zs(ByRef input_number){
  move_window(input_number, 5, "A")
}
key_zd(ByRef input_number){
  move_window(input_number, 6, "A")
}
key_zz(ByRef input_number){
  move_window(input_number, 1, "A")
}
key_zx(ByRef input_number){
  move_window(input_number, 2, "A")
}
key_zc(ByRef input_number){
  move_window(input_number, 3, "A")
}
/*
  <END> 2 char commands -----------------
*/

/*
  Control Mouse Pointer movement By w a s d
  w : up
  a : left
  s : down
  d : right
*/
key_w(ByRef input_number) {
  if(input_number = "") {
    input_number = 1
    func_mouse_move( input_number , 1, 1, 1 )
  }
}
key_a(ByRef input_number) {
  if( GetKeyState("Shift") ) {
    func_i_o_a("a")
  } else if(input_number = "")
    input_number = 1
  func_mouse_move( 1, input_number, 1, 1 )
}
key_s(ByRef input_number) {
  if(input_number = "")
    input_number = 1
  func_mouse_move( 1, 1, input_number, 1 )
}
key_d(ByRef input_number) {
  if(input_number = "")
    input_number = 1
  func_mouse_move( 1, 1, 1, input_number )
}

/*
  q : Click Mouse Left Button
  ^q : Click Hold
  +q : unHold
*/
key_q(ByRef input_number) {
  if( GetKeyState("Control"))
    Click Down Left
  else if( GetKeyState("Shift"))
    Click Up Left
  else
    Click, Left, %input_number%
}

/*
  e : Click Mouse Right Button
  ^e : Click Hold
  +e : unHold
*/
key_e(ByRef input_number) {
  if( GetKeyState("Control") )
    Click Down Right
  else if( GetKeyState("Shift") )
    Click Up Right
  else
    Click, Right, %input_number%
}

/*
  i, o, a : mode changer
*/
key_i(ByRef input_number){
  func_i_o_a("i")
}
key_o(ByRef input_number){
  func_i_o_a("o")
}

/*
  0 : Home
  $ : End
*/
key_0(ByRef input_number) {
  Send, {Home}
}
key_4(ByRef input_number) {
  if(GetKeyState("shift", "P"))
    Send, {End}
}

/*
  p : paste
  y : copy
*/
key_p(ByRef input_number){
  Send, ^{v %input_number%}
}
key_y(ByRef input_number){
  temp := Clipboard
  Send, ^{c}
  Sleep 500

  if(input_number = ""){
    CLIP.num_unshift(Clipboard)
  } else {
    CLIP.set_value(input_number, Clipboard)
  }
  Clipboard := temp
}

/*
  f  : Mouse Wheel Down
  ^f : Page Down
*/
key_f(ByRef input_number) {
  if( GetKeyState("Control") )
    Send, {PGDN %input_number%}
  else
    MouseClick, WheelDown, , , input_number
}

/*
  r : Mouse Wheel Up
*/
key_r(ByRef input_number) {
  MouseClick, WheelUp, , , input_number
}

/*
  b  : previous word (^left)
  +b : next word (^right)
  ^b : Page Up
*/
key_b(ByRef input_number) {
  if( GetKeyState("Control") )
    Send, {PGUP %input_number%}
  else if( GetKeyState("Shift") )
    Send, ^{Right %input_number%}
  else
    Send, ^{Left %input_number%}
}

/*
  u : undo
*/
key_u(ByRef input_number){
  if(input_number <> "")
    Send, ^{z %input_number%}
}

/*
  x, +x : delete, backspace
*/
key_x(ByRef input_number){
  if(GetKeyState("Control"))
    Send, ^{x}
  else if(GetKeyState("Shift"))
    Send, {BackSpace %input_number%}
  else if(input_number <> "")
    Send, {Delete %input_number%}
}

/*
  do nothing
*/
key_c(ByRef input_number){
}
key_n(ByRef input_number){
}
key_t(ByRef input_number){
}
key_v(ByRef input_number){
  if(GetKeyState("Shift")){
    Send, {ShiftUp}
  } else {
    Send, {ShiftDown}
  }
}

/*
  H J K L move
*/
/*
key_h(ByRef input_number) {
  Send {Left %input_number%}
}
key_j(ByRef input_number) {
  Send {Down %input_number%}
}
key_k(ByRef input_number) {
  Send {Up %input_number%}
}
key_l(ByRef input_number) {
  Send {Right %input_number%}
}
*/


Map Browser_Search to F8

Map Browser_Search to F8

Browser_Back::Esc
Capslock::Ctrl

Browser_Home::F1

; The Keys-To-Go keyboard has a task-switching
; hotkey in place of the F2 key. It works by
; signaling LAlt and then Tab.
;
; Unfortunately, it's not immediately obvious
; how to distinguish an emulated LAlt+Tab from
; a real one. The solution will likely involve
; determining the exact timing of the emulated
; chord.
;
; Until I've figured that out, LAlt+Tab will
; trigger F2 even when I'm pressing the chord
; myself.
LAlt & Tab::Send {F2}

AppsKey::F3
Launch_Mail::F4
Launch_Media::F5
Media_Prev::F6
Media_Play_Pause::F7

; This keyboard only has 11 hotkeys along the
; top. Of the 12 traditional function keys, I
; use F8 least frequently, so I'm moving it
; to the Browser_Search key (left of the arrow
; keys).
Browser_Search::F8

Media_Next::F9
Volume_Down::F10
Volume_Up::F11
PrintScreen::F12

Browser_Back::Esc
Capslock::Ctrl

Browser_Home::F1

; The Keys-To-Go keyboard has a task-switching
; hotkey in place of the F2 key. It works by
; signaling LAlt and then Tab.
;
; Unfortunately, it's not immediately obvious
; how to distinguish an emulated LAlt+Tab from
; a real one. The solution will likely involve
; determining the exact timing of the emulated
; chord.
;
; Until I've figured that out, LAlt+Tab will
; trigger F2 even when I'm pressing the chord
; myself.
LAlt & Tab::Send {F2}

AppsKey::F3
Launch_Mail::F4
Launch_Media::F5
Media_Prev::F6
Media_Play_Pause::F7

; This keyboard only has 11 hotkeys along the
; top. Of the 12 traditional function keys, I
; use F8 least frequently, so that's the one
; I'm skipping.

Media_Next::F9
Volume_Down::F10
Volume_Up::F11
PrintScreen::F12


AutoHotkey.ahk, from darwin17

AutoHotkey.ahk, from darwin17

; Tips {{{
; #: win
; !: alt
; ^: ctrl
; +: shift
; &: and
; <: only left, >: only right
; *: wildecard
; ~: pass through
; }}}

; Auto execute section is the region before any return/hotkey {{{
; Windows size
TMargin := 5
BMargin := 5
LMargin := 5
RMargin := 5 ; sidebar = 150px
MinSize := 0.7

; For Terminal/Vim
GroupAdd Terminal, ahk_class PuTTY
GroupAdd Terminal, ahk_class mintty ; cygwin
GroupAdd Terminal, ahk_class TMobaXtermForm
GroupAdd Terminal, ahk_class TFormDetachedTab
GroupAdd Terminal, ahk_class ConsoleWindowClass
GroupAdd Terminal, ahk_exe powershell.exe
GroupAdd Terminal, ahk_exe vim.exe
GroupAdd TerminalVim, ahk_group Terminal
GroupAdd TerminalVim, ahk_class Vim

; For browsers
GroupAdd, Browser, ahk_exe chrome.exe
GroupAdd, Browser, ahk_exe firefox.exe
GroupAdd, Browser, ahk_exe ApplicationFrameHost.exe ; Edge

; Mouse Gestures
GroupAdd, MouseGesture, ahk_group Broser
GroupAdd, MouseGesture, ahk_exe explorer.exe

; External files
VimIcon := 1
#Include %A_LineFile%\..\submodules\vim_ahk\vim.ahk
#Include %A_LineFile%\..\AutoCorrect.ahk

Return
; }}}

;; Basic Settings, HotKeys, Functions {{{
; Settings

#UseHook On ; Make it a bit slow, but can avoid infinitude loop
            ; Same as "$" for each hotkey
#InstallKeybdHook ; For checking key history
                  ; Use ~500kB memory?

#HotkeyInterval 1000 ; Hotkey inteval (default 2000 milliseconds).
#MaxHotkeysPerInterval 100 ; Max hotkeys perinterval (default 50).

; For HHKB
;vkFFsc079::RCtrl
;vkFFsc07b::LCtrl
; }}}

; Terminal/Vim {{{
; ESC + IME
#IfWInActive, ahk_group TerminalVim
Esc:: ; Just send Esc at converting.
  if(VIM_IME_GET(A)){
    if(VIM_IME_GetConverting(A)){
      Send, {Esc}
    }else{
      VIM_IME_SET()
    }
  }else{
    Send, {Esc}
  }
Return

^[:: ; Go to Normal mode (for vim) with IME off even at converting.
  if(VIM_IME_GetConverting(A)){
    Send, {Esc}
    Sleep 1 ; wait 1 ms (Need to stop converting)
  }
  if(VIM_IME_GET(A)){
    VIM_IME_SET()
    Send, {Esc}
  }else{
    Send, {Esc}
  }
Return

^m::Send, ^m ; Use Ctrl-m as is

; Paste
#IfWInActive, ahk_group Terminal
!v::
  ;StringSplit, strout, clipboard, `n
  ;If(strout0>1 or InStr(clipboard, "sudo")>0){
  ;  MsgBox, 308, Clipboard, %clipboard%`n`n Do you want to paste?
  ;  IfMsgBox, No
  ;  {
  ;    Return
  ;  }
  ;}
  ;SendInput %clipboard%
  ;Return
  Sleep,200
  MouseClick, Right, 50, 50, 1
Return

#IfWInActive, ahk_class Vim
!v::Send, {Alt}ep

; Other than Terminal/Vim
#IfWInNotActive, ahk_group TerminalVim
^[::Send, {Esc}             ; Always C-[ to ESC, like vim
^d::Send, {Del}             ; Always Delete with C-d
; }}} Terminal/Vim

; Power Point {{{
#IfWInActive, ahk_class PP12FrameClass
; Subscript/Superscript
^=::Send, ^tb{Enter}
^+=::Send, ^tp{Enter}
; For JP keyboards
;^-::Send, ^tb{Enter}
;^+-::Send, ^tp{Enter}

; Fonts
^!+s::Send, ^tfsymbol{Enter}
^!+a::Send, ^tfarial{Enter}
^!+h::Send, ^tfhelvetica{Enter}
; }}} Power Point

; Word {{{
#IfWInActive, ahk_class OpusApp
^=::Send, ^tb{Enter}
^+=::Send, ^tp{Enter}
; for JP keyboards
;^-::Send, ^tb{Enter}
;^+-::Send, ^tp{Enter}
; }}} Word

; Explorer {{{
#IfWInActive, ahk_class CabinetWClass
; Next/Previous page
^i::Send, !{Right}
^o::Send, !{Left}
; }}} Explorer

; CLCL {{{
;#IfWInActive, ahk_class CLCLMain
#IfWInActive, CLCL ; both window/title do not working...
j::
  Msgbox, clcl_down
  Send, {Down}
Return

K::Send, {Up}
; }}} Explorer

; Everthing {{{
#IfWinActive, ahk_class EVERYTHING
Return::
  Send, {Enter}
  Sleep, 200
  IfWinActive, ahk_class EVERYTHING
  {
    Send,{Enter}
    Sleep, 500
  }
  WinActivate, ahk_class EVERYTHING
  Sleep, 200
  Send, {Esc}
Return
; }}} Everything

; Firefox/Chrome/Edge {{{
#IfWinActive, ahk_group Browser
;^WheelDown::Send, {WheelDown}
;^WheelUp::Send, {WheelUp}
^WheelDown::Return
^WheelUp::Return
; }}} Firefox/Chrome

; Mouse Gestures {{{
#IfWinActive, ahk_group MouseGesture
;LButton & RButton::Send, ^{Tab}
;RButton & LButton::Send, ^+{Tab}

; }}} Firefox/Chrome

; Global Settings {{{
#if
; Basic Settings {{{

; Suspend
;Esc & Tab::
;  Suspend, Toggle
;  Return
; For Alt-Ctrl Swap (swapped by KeySwap)
; To assign ^Tab, need to add < or > to choose left or right
<^Tab::AltTab
;<+<^Tab::ShiftAltTab ; can not assigned...
;LCtrl & Tab::
;  if GetKeyState("Shift","P"){
;    Send, {ShiftAltTab}
;  }else{
;    Send, {AltTab}
;  }
;Return
;Alt & Tab::
;  if GetKeyState("Shift","P"){
;    Send, ^+{taB}
;  }else{
;    Send, ^{Tab}
;  }
;Return
!Tab::Send, ^{Tab}
!+Tab::Send, ^+{Tab}

;!m::Send, ^m
;^m::Send, !m
;>^m::Send, !m
;Ctrl & Left::Send, !{Left}
;Ctrl & Right::Send, !{Right}

; Virtual desktop
^!+h::Send, #^{Left}
^!+l::Send, #^{Right}

; Cortana
!^f::Send, #s

; CLCL
#c::Send, !c

; Other basic settings
!Space::Send, {vkF3sc029} ; IME by A-Space
^Space::Send, {vkF3sc029} ; IME by C-Space
;{vkF3sc029}               ; 変換
;{vk1Dsc07B}               ; 無変換
!^a::Send, !{Space}n       ; Minimize window
!4::Send, !{F4}           ; Close window
^4::Send, !{F4}           ; Close window
!d::Send, {Del}           ; Always Delete with A-d
;^o::Send,!{Left}          ; Go to previous page
;^i::Send,!{Right}         ; Go to nexe page
^Space::!`                ; IME

^h::Send, {BS}            ; Always BS with C-h
;^h::
;  While GetKeyState("h","p"){
;    Send {BS}
;    TrayTip,Start:,%n%,10,,
;    Sleep 50
;  }
;  return

;^j::Send,{Enter}      ; C-j to Enter

; For HHKB
; ESC to ` like normal keyboard (ESC is placed on the left of 1 in HHKB)
!1::!`                ; IME
; }}} Basic Settings

; Cursor, Mouse, Window move/size {{{
; Cursor {{{
!^h::Send, {Left}
!^j::Send, {Down}
!^k::Send, {Up}
!^l::Send, {Right}
; }}} Cursor

; Mouse {{{
; Mouse Move
^+h::MouseMove, -10, 0, 0, R
^+j::MouseMove, 0, 10, 0, R
^+k::MouseMove, 0, -10, 0, R
^+l::MouseMove, 10, 0, 0, R

; Click
^+n::MouseClick, Left
^+p::MouseClick, Right
; Right click on current window

; Mouse wheel
!^m::MouseClick, WheelDown, , , 2
!^,::MouseClick, WheelUp, , , 2
; }}} Mouse

; Window move {{{

; Move a little
^+y::
  WinGetPos, X, Y, , , A ;A for Active Window
  WinMove, A, ,X-20, Y,
Return

^+u::
  WinGetPos, X, Y, , , A
  WinMove, A, , X, Y+20
Return

^+i::
  WinGetPos, X, Y, , , A
  WinMove, A, , X, Y-20
Return

^+o::
  WinGetPos, X, Y, , , A
  WinMove, A, , X+20, Y
Return

; Move to a different screen
!^+y:: Send, #+{Left}
!^+u:: Send, #+{Down}
!^+i:: Send, #+{Up}
!^+o:: Send, #+{Right}

; }}} Window move

; Window size {{{

; Almost full
^!Enter::
!+Enter::
  ;WinGetPos, X, Y, W, H, Program Manager ; Full Desktop
  ;Msgbox, Pos At %X% %Y% %W% %H%
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  ;Msgbox, %MWALeft% %MWATop% %MWARight% %MWABottom%
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , MWARight-MWALeft-LMargin-RMargin
    , MWABottom-MWATop-TMargin-BMargin
Return

; Minsize
^!+Enter::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , (MWARight-MWALeft-LMargin-RMargin)*Minsize
    , (MWABottom-MWATop-TMargin-BMargin)*Minsize
Return

; Half size
!+h::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , (MWARight-MWALeft-LMargin-RMargin)*0.5
    , MWABottom-MWATop-TMargin-BMargin
Return

!+j::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin
    , MWATop+(MWABottom-MWATop)*0.5
    , MWARight-MWALeft-LMargin-RMargin
    , (MWABottom-MWATop-TMargin-BMargin)*0.5
Return

!+k::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , MWARight-MWALeft-LMargin-RMargin
    , (MWABottom-MWATop-TMargin-BMargin)*0.5
Return

!+l::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+(MWARight-MWALeft)*0.5
    , MWATop+TMargin
    , (MWARight-MWALeft-LMargin-RMargin)*0.5
    , MWABottom-MWATop-TMargin-BMargin
Return

; Resize
!+y::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W-20, H
Return

!+u::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W, H+20
Return

!+i::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W, H-20
Return

!+o::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W+20, H
Return

; }}} Window size
; }}} Cursor, Mouse, Window move
; }}} Global Settings

; Tips {{{
; #: win
; !: alt
; ^: ctrl
; +: shift
; &: and
; <: only left, >: only right
; *: wildecard
; ~: pass through
; }}}

; Auto execute section is the region before any return/hotkey {{{
; Windows size
TMargin := 5
BMargin := 5
LMargin := 5
RMargin := 5 ; sidebar = 150px
MinSize := 0.7

; For Terminal/Vim
GroupAdd Terminal, ahk_class PuTTY
GroupAdd Terminal, ahk_class mintty ; cygwin
GroupAdd Terminal, ahk_class TMobaXtermForm
GroupAdd Terminal, ahk_class TFormDetachedTab
GroupAdd Terminal, ahk_class ConsoleWindowClass
GroupAdd Terminal, ahk_exe powershell.exe
GroupAdd Terminal, ahk_exe vim.exe
GroupAdd TerminalVim, ahk_group Terminal
GroupAdd TerminalVim, ahk_class Vim

; For browsers
GroupAdd, Browser, ahk_exe chrome.exe
GroupAdd, Browser, ahk_exe firefox.exe
GroupAdd, Browser, ahk_exe ApplicationFrameHost.exe ; Edge

; Mouse Gestures
GroupAdd, MouseGesture, ahk_group Broser
GroupAdd, MouseGesture, ahk_exe explorer.exe

; External files
VimIcon := 1
#Include %A_LineFile%\..\submodules\vim_ahk\vim.ahk
#Include %A_LineFile%\..\AutoCorrect.ahk

Return
; }}}

;; Basic Settings, HotKeys, Functions {{{
; Settings

#UseHook On ; Make it a bit slow, but can avoid infinitude loop
            ; Same as "$" for each hotkey
#InstallKeybdHook ; For checking key history
                  ; Use ~500kB memory?

#HotkeyInterval 1000 ; Hotkey inteval (default 2000 milliseconds).
#MaxHotkeysPerInterval 100 ; Max hotkeys perinterval (default 50).

; For HHKB
;vkFFsc079::RCtrl
;vkFFsc07b::LCtrl
; }}}

; Terminal/Vim {{{
; ESC + IME
#IfWInActive, ahk_group TerminalVim
Esc:: ; Just send Esc at converting.
  if(VIM_IME_GET(A)){
    if(VIM_IME_GetConverting(A)){
      Send, {Esc}
    }else{
      VIM_IME_SET()
    }
  }else{
    Send, {Esc}
  }
Return

^[:: ; Go to Normal mode (for vim) with IME off even at converting.
  if(VIM_IME_GetConverting(A)){
    Send, {Esc}
    Sleep 1 ; wait 1 ms (Need to stop converting)
  }
  if(VIM_IME_GET(A)){
    VIM_IME_SET()
    Send, {Esc}
  }else{
    Send, {Esc}
  }
Return

^m::Send, ^m ; Use Ctrl-m as is

; Paste
#IfWInActive, ahk_group Terminal
!v::
  ;StringSplit, strout, clipboard, `n
  ;If(strout0>1 or InStr(clipboard, "sudo")>0){
  ;  MsgBox, 308, Clipboard, %clipboard%`n`n Do you want to paste?
  ;  IfMsgBox, No
  ;  {
  ;    Return
  ;  }
  ;}
  ;SendInput %clipboard%
  ;Return
  Sleep,200
  MouseClick, Right, 50, 50, 1
Return

#IfWInActive, ahk_class Vim
!v::Send, {Alt}ep

; Command Promp, PowerShell, Bash on Ubuntu on Windows {{{
#IfWinActive ahk_class ConsoleWindowClass
^v::Send, ^q
!v::
  SendInput %clipboard%
Return
; }}} Command Prompt

; Other than Terminal/Vim
#IfWInNotActive, ahk_group TerminalVim
^[::Send, {Esc}             ; Always C-[ to ESC, like vim
^d::Send, {Del}             ; Always Delete with C-d
; }}} Terminal/Vim

; Power Point {{{
#IfWInActive, ahk_class PP12FrameClass
; Subscript/Superscript
^=::Send, ^tb{Enter}
^+=::Send, ^tp{Enter}
; For JP keyboards
;^-::Send, ^tb{Enter}
;^+-::Send, ^tp{Enter}

; Fonts
^!+s::Send, ^tfsymbol{Enter}
^!+a::Send, ^tfarial{Enter}
^!+h::Send, ^tfhelvetica{Enter}
; }}} Power Point

; Word {{{
#IfWInActive, ahk_class OpusApp
^=::Send, ^tb{Enter}
^+=::Send, ^tp{Enter}
; for JP keyboards
;^-::Send, ^tb{Enter}
;^+-::Send, ^tp{Enter}
; }}} Word

; Explorer {{{
#IfWInActive, ahk_class CabinetWClass
; Next/Previous page
^i::Send, !{Right}
^o::Send, !{Left}
; }}} Explorer

; CLCL {{{
;#IfWInActive, ahk_class CLCLMain
#IfWInActive, CLCL ; both window/title do not working...
j::
  Msgbox, clcl_down
  Send, {Down}
Return

K::Send, {Up}
; }}} Explorer

; Everthing {{{
#IfWinActive, ahk_class EVERYTHING
Return::
  Send, {Enter}
  Sleep, 200
  IfWinActive, ahk_class EVERYTHING
  {
    Send,{Enter}
    Sleep, 500
  }
  WinActivate, ahk_class EVERYTHING
  Sleep, 200
  Send, {Esc}
Return
; }}} Everything

; Firefox/Chrome/Edge {{{
#IfWinActive, ahk_group Browser
;^WheelDown::Send, {WheelDown}
;^WheelUp::Send, {WheelUp}
^WheelDown::Return
^WheelUp::Return
; }}} Firefox/Chrome

; Mouse Gestures {{{
#IfWinActive, ahk_group MouseGesture
;LButton & RButton::Send, ^{Tab}
;RButton & LButton::Send, ^+{Tab}

; }}} Firefox/Chrome

; Global Settings {{{
#if
; Basic Settings {{{

; Suspend
;Esc & Tab::
;  Suspend, Toggle
;  Return
; For Alt-Ctrl Swap (swapped by KeySwap)
; To assign ^Tab, need to add < or > to choose left or right
<^Tab::AltTab
;<+<^Tab::ShiftAltTab ; can not assigned...
;LCtrl & Tab::
;  if GetKeyState("Shift","P"){
;    Send, {ShiftAltTab}
;  }else{
;    Send, {AltTab}
;  }
;Return
;Alt & Tab::
;  if GetKeyState("Shift","P"){
;    Send, ^+{taB}
;  }else{
;    Send, ^{Tab}
;  }
;Return
!Tab::Send, ^{Tab}
!+Tab::Send, ^+{Tab}

;!m::Send, ^m
;^m::Send, !m
;>^m::Send, !m
;Ctrl & Left::Send, !{Left}
;Ctrl & Right::Send, !{Right}

; Virtual desktop
^!+h::Send, #^{Left}
^!+l::Send, #^{Right}

; Cortana
!^f::Send, #s

; CLCL
#c::Send, !c

; Other basic settings
!Space::Send, {vkF3sc029} ; IME by A-Space
^Space::Send, {vkF3sc029} ; IME by C-Space
;{vkF3sc029}               ; 変換
;{vk1Dsc07B}               ; 無変換
!^a::Send, !{Space}n       ; Minimize window
!4::Send, !{F4}           ; Close window
^4::Send, !{F4}           ; Close window
!d::Send, {Del}           ; Always Delete with A-d
;^o::Send,!{Left}          ; Go to previous page
;^i::Send,!{Right}         ; Go to nexe page
^Space::!`                ; IME

^h::Send, {BS}            ; Always BS with C-h
;^h::
;  While GetKeyState("h","p"){
;    Send {BS}
;    TrayTip,Start:,%n%,10,,
;    Sleep 50
;  }
;  return

;^j::Send,{Enter}      ; C-j to Enter

; For HHKB
; ESC to ` like normal keyboard (ESC is placed on the left of 1 in HHKB)
!1::!`                ; IME
; }}} Basic Settings

; Cursor, Mouse, Window move/size {{{
; Cursor {{{
!^h::Send, {Left}
!^j::Send, {Down}
!^k::Send, {Up}
!^l::Send, {Right}
; }}} Cursor

; Mouse {{{
; Mouse Move
^+h::MouseMove, -10, 0, 0, R
^+j::MouseMove, 0, 10, 0, R
^+k::MouseMove, 0, -10, 0, R
^+l::MouseMove, 10, 0, 0, R

; Click
^+n::MouseClick, Left
^+p::MouseClick, Right
; Right click on current window

; Mouse wheel
!^m::MouseClick, WheelDown, , , 2
!^,::MouseClick, WheelUp, , , 2
; }}} Mouse

; Window move {{{

; Move a little
^+y::
  WinGetPos, X, Y, , , A ;A for Active Window
  WinMove, A, ,X-20, Y,
Return

^+u::
  WinGetPos, X, Y, , , A
  WinMove, A, , X, Y+20
Return

^+i::
  WinGetPos, X, Y, , , A
  WinMove, A, , X, Y-20
Return

^+o::
  WinGetPos, X, Y, , , A
  WinMove, A, , X+20, Y
Return

; Move to a different screen
!^+y:: Send, #+{Left}
!^+u:: Send, #+{Down}
!^+i:: Send, #+{Up}
!^+o:: Send, #+{Right}

; }}} Window move

; Window size {{{

; Almost full
^!Enter::
!+Enter::
  ;WinGetPos, X, Y, W, H, Program Manager ; Full Desktop
  ;Msgbox, Pos At %X% %Y% %W% %H%
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  ;Msgbox, %MWALeft% %MWATop% %MWARight% %MWABottom%
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , MWARight-MWALeft-LMargin-RMargin
    , MWABottom-MWATop-TMargin-BMargin
Return

; Minsize
^!+Enter::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , (MWARight-MWALeft-LMargin-RMargin)*Minsize
    , (MWABottom-MWATop-TMargin-BMargin)*Minsize
Return

; Half size
!+h::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , (MWARight-MWALeft-LMargin-RMargin)*0.5
    , MWABottom-MWATop-TMargin-BMargin
Return

!+j::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin
    , MWATop+(MWABottom-MWATop)*0.5
    , MWARight-MWALeft-LMargin-RMargin
    , (MWABottom-MWATop-TMargin-BMargin)*0.5
Return

!+k::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+LMargin, MWATop+TMargin
    , MWARight-MWALeft-LMargin-RMargin
    , (MWABottom-MWATop-TMargin-BMargin)*0.5
Return

!+l::
  SysGet, MWA, MonitorWorkArea ; w/o Taskbar
  WinMove, A, , MWALeft+(MWARight-MWALeft)*0.5
    , MWATop+TMargin
    , (MWARight-MWALeft-LMargin-RMargin)*0.5
    , MWABottom-MWATop-TMargin-BMargin
Return

; Resize
!+y::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W-20, H
Return

!+u::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W, H+20
Return

!+i::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W, H-20
Return

!+o::
  WinGetPos, X, Y, W, H, A
  WinMove, A, ,X, Y, W+20, H
Return

; }}} Window size
; }}} Cursor, Mouse, Window move
; }}} Global Settings


Code style

Code style

/*
API 函数列表：
vim.mode("模式", "ahk_class")  ; 设置运行的模式
vim.map("热键", "Label标签", "ahk_class")  ;映射热键
vim.settimeout("按键超时时间", "ahk_class")  ;设置按键超时时间
vim.listkey("ahk_class")  ;显示所有映射的热键体
vim.control("on/off", "ahk_class")  ;启用/禁用映射的热键
vim.comment("标签", "描述", "是否允许多次运行（0/1)")
内置Label:
<Repeat> 重复上一次动作
*/

#UseHook On
Setkeydelay, -1
return

; 此函数可以根据自己的喜好进行修改
ShowComment(more = "") {
    if not ToShowComment
        return

    WinGetClass, win, A
    w := vim.Vaild(win)
    mode := w.GetMode()
    msg := mode.KeyTemp "`n=============================`n"
    ;GUIControl, , Edit1, %msg%

    if Strlen(more)
    {
        Loop, Parse, more, `n
        {
            key := Trim(A_LoopField)
            action := mode.KeyBody[key]
            ;comment := vim.CommentList[action]
            comment := GetCommentDest(action)
            if Strlen(comment)
                msg .= key "  >>  " comment "`n"
            else
                msg .= key "  >>  " action "`n"

        }
        Tooltip % msg
        ;GUI, VIMINFO:Show
    }
    else
        Tooltip
        ;GUI, VIMINFO:Show, Hide
}

; ====================
; ====================
; 内部脚本，请匆修改！
; ====================
; ====================

; 初始化 vimcore
Init() {
    OnMessage(0x05, "GuiSize")
    GoSub, vimnew
}

vimnew:
    Global vim := new vimcore
return

; 以下为class封装，请匆修改
Class vimcore {
    __New() {
       This.vimWindows := []
       This.vimGlobal  := new This.vimClass("")
       This.TimeOutClass := ""
       This.ExcludeList := []
       ;This.ExcludeList["AutoHotkey"] := True
       This.CommentList := []
       This.CommentType := []
       This.UseHotkey   := []
    }

    Vaild(win) {
        if Strlen(win) = 0
            Return This.vimGlobal
        w := This.vimWindows[win]
        if w.winVaild
            return w
        else
            return This.vimGlobal
    }

    mode(mode, win = "") {
        if Strlen(win) = 0
            w := This.vimGlobal
        else
            w := This.vimWindows[win]
        if not w.winVaild
        {
            w := new This.vimClass(win)
            This.vimWindows[win] := w
        }
        w.SetMode(mode)
        ShowComment()
    }

    sMap(key, label, win = ""){
        This.UseHotkey[key] := True
        this.Map(key, label, win)
    }

    Map(key, label, win = "") {
        if not RegExMatch(Key, "[^\s]")
            return
        if Strlen(win) = 0
            w := This.vimGlobal
        else
            w := This.vimWindows[win]
        if not w.winVaild
        {
            w := new This.vimClass(win)
            This.vimWindows[win] := w
        }
        mode := w.GetMode()
        mode.SetHotkey(key, label)
    }

    Comment(action, desc, complex=1) {
        This.CommentList[action] := desc
        This.CommentType[action] := complex
    }

    do() {
        WinGetClass, win, A
        w := This.Vaild(win)
        m := w.GetMode()
        if This.ExcludeList[win] And not this.UseHotkey[m.GetThisHotkey()]
        {
            Send, % m.TransSendKey(A_ThisHotkey)
            return
        }
        if w.winVaild {
            mode := w.GetMode()
            if Mode.KeyList[A_ThisHotkey]
                mode.Try()
            else
            {
                w := This.vimGlobal
                mode := w.GetMode()
                mode.Try()
            }
        }
    }

    Filter(String) {

        WinGetClass, win, A

        if This.ExcludeList[win]
            return
        w := This.Vaild(win)

        if w.winVaild {
            mode := w.GetMode()
            mode.query(string)
        }
    }

    Exclude(win) {
        This.ExcludeList[win] := True
    }

    Include(win) {
        This.ExcludeList[win] := False
    }

    ListKey(win = "", mode = "") {
        w := This.Vaild(win)
        if strlen(mode) {
            m := w.winmode[mode]
            For k , l in m.KeyBody
                msg .= k "  " l "`n"
            return msg
        } else {
            For n , m  in w.winMode
            {
                msg .= "====`n" n "`n----`n"
                mode := m
                For k , l in m.KeyBody
                    msg .= k "  " l "`n"
            }
            return msg
        }
    }

    copy(win1, win2) {

        w2 := This.vimWindows[win2]

        if w2.winVaild
            return False

        w1 := This.Vaild(win1)
        w1.winName := win2
        For n , m in w1.WinMode
        {
            mode := m
            mode.win := win2
            w1.WinMode[n] := mode
            For k , l in m.KeyList
            {
                Hotkey, IfWinActive, ahk_class %win2%
                Hotkey, %k%, <HotkeyLabel>
            }
        }
        This.vimWindows[win2] := w1
        return True
    }

    CopyMode(win, mode, to) {
        w := This.Vaild(win)
        if strlen(mode) = 0
            return

        vim.mode(to, win)
        m := w.winmode[mode]
        For k , l in m.KeyBody
            vim.map(k, l, win)
    }

    Control(switch, win = "") {
        w := This.Vaild(win)
        if switch = on
        {
            For n , m  in w.winMode
            {
                mode := m
                For k , l in m.KeyList
                {
                    Hotkey, %k%, on
                }
            }
        }
        if switch = off
        {
            For n , m  in w.winMode
            {
                mode := m
                For k , l in m.KeyList
                {
                    Hotkey, %k%, off
                }
            }
        }
    }

    test() {
        msgbox vim test
    }

    SetTimeOut(tick, win = "") {
        w := This.Vaild(win)
        if not w.winVaild
        {
            w := new This.vimClass(win)
            This.vimWindows[win] := w
        }
        w.TimeOut := tick
    }

    TimeOut() {
        w := This.Vaild(This.TimeOutClass)
        mode := w.GetMode()
        mode.KeyTemp := ""
        ;GoSub, % mode.TimeOutAction
        mode.ExecSub(mode.TimeOutAction)
        ;    ShowComment()
        mode.TimeOutAction := ""
    }

    Repeat() {
        WinGetClass, win, A
        w := This.vimWindows[win]
        if not w.winVaild
            w := This.vimGlobal
        if w.winVaild {
            mode := w.GetMode()
            mode.KeyCount := w.winRepeatCount
            mode.ExecSub(w.winRepeat, Ture)
        }
    }

    GetWin() {
        WinGetClass, win, A
        Return This.Vaild(win)
    }

    GetCount() {
        w := This.GetWin()
        m := w.GetMode()
        Return m.KeyCount ? m.KeyCount : 1
    }

    Class vimClass {

        __New(win) {
            This.winName := win
            This.winVaild   := 1
            This.winControl := 0
            This.winTimeOut := 0
            THis.winMaxCount := 99
            This.winKeyList := []
            This.winMode    := []
            This.winThisMode := ""
            This.winRepeat   := ""
            This.winRepeatCount := 0
        }
        ;设置窗口类下的模式
        SetMode(md) {
            m := This.winMode[md]
            if Strlen(m.Mode) = 0 {
                This.winThisMode := md
                m := new This.Mode(md, This.winName)
                This.winMode[md] := m
            }
            else
                This.winThisMode := md
            return m
        }
        ;获取窗口类下的模式

        GetMode() {
            m := This.winMode[This.winThisMode]
            return m
        }

        Class Mode {
            __New(mode, win) {
                This.Mode := mode
                This.win  := win ;可变
                if Strlen(win)
                    This.CheckMode := win "_CheckMode"
                else
                    This.CheckMode := "CheckMode"
                This.KeyTemp   := ""
                This.KeyString := ""
                This.KeyCount := 0
                This.TimeOut := 0
                This.TimeOutTick   := 0
                This.TimeOutAction := ""
                This.KeyBody := []
                This.KeyList := []
                This.KeyMap  := []
            }

            test() {
                msgbox % This.Mode
            }

            Try(){
                checkMode := This.CheckMode
                settimer, <TimeOutLabel>, off
                Key := This.GetThisHotkey()
                if ( Not This.KeyList[A_ThisHotkey] ) or ( IsFunc(CheckMode) AND (%CheckMode%()) ) {
                    Send, % This.TransSendKey(A_ThisHotkey)
                    ShowComment()
                    return
                }
                _SaveKeyTemp := This.KeyTemp
                This.KeyTemp .= Key
                P := 1
                more := ""
                moreCount := 0
                Loop {
                    P := RegExMatch(This.KeyString, "i)\t" This.ToMatch(This.keyTemp) "[^\t]*", m, P)
                    if P {
                        ;msgbox % This.KeyString "`np = " p "`nm = " m
                        more .= m "`n"
                        P += Strlen(m)
                        moreCount++
                    }
                    else
                        Break
                }
                more := RTrim(more, "`n")
                if moreCount = 0
                {
                    This.KeyTemp := ""

                    action := This.KeyBody[_SaveKeyTemp]
                    if Strlen(action) {
                        This.ExecSub(Action)
                    }
                    else {
                        action := This.KeyBody[Key]
                        if Strlen(action) {
                            if InvalidMode
                                ShowComment()
                            else
                                This.ExecSub(Action)
                        }
                        else {
                            if RegExMatch(This.KeyString, "i)\t" This.ToMatch(key) "[^\t]*")
                            {
                                if InvalidMode
                                    ShowComment()
                                else
                                    This.Try()
                            }
                            else
                            {
                                Send, % This.TransSendKey(A_ThisHotkey)
                                ShowComment()
                            }
                            return
                        }
                    }
                }
                else if moreCount = 1
                {
                    Action := This.KeyBody[This.KeyTemp]
                    if Strlen(Action) {
                        This.ExecSub(Action)
                        This.KeyTemp := ""
                    }
                    else
                        ShowComment(more)
                }
                else
                {
                    TimeOut := 0 - GetTimeOutClass(This.win)
                    if Timeout And This.KeyBody[This.KeyTemp]{
                        This.TimeOutAction := This.KeyBody[This.KeyTemp]
                        This.TimeOutTick   := A_TickCount
                        SetTimeOutClass(This.win)
                        Settimer, <TimeOutLabel>, %TimeOut%
                    }
                    ErrorLevel := True
                    ShowComment(more)
                    return more
                }
            }

            ExecSub(action) {
                w := vim.vaild(This.win)
                if RegExMatch(Action, "(?<=^<)\d(?=>$)", cnt) {
                        This.KeyCount := This.KeyCount * 10 + cnt
                        MaxCount := w.winMaxCount
                        if This.KeyCount > MaxCount
                            This.KeyCount := MaxCount
                        Tooltip % This.KeyCount
                        return false
                }
                else {
                    ShowComment()
                    if This.KeyCount And GetCommentType(Action)
                        cnt := This.KeyCount
                    else
                        cnt := 1
                    ;cnt := This.KeyCount ? This.KeyCount : 1
                    if RegExMatch(action, "^<.*>$") {
                        if IsLabel(action) {
                            Loop, %cnt%
                                GoSub % Action
                        }
                        else {
                            Msgbox %Action%不存在，请检查脚本
                            Return
                        }
                    }
                    if RegExMatch(action, "^\(.*\)$") {
                        file := SubStr(action, 2, Strlen(action)-2)
                        Run, %File%, , UseErrorLevel, ExecID
                        if ErrorLevel
                        {
                            msgbox 运行%file%失败
                            return
                        }
                        else
                        {
                            WinWait, AHK_PID %ExecID%, , 1
                            WinActivate, AHK_PID %ExecID%
                        }
                    }
                    if RegExMatch(Action, "^\{.*\}$") {
                        Text := Substr(Action, 2, Strlen(Action)-2)
                        Loop, %cnt%
                            Send, %Text%
                    }

                    This.KeyCount := 0
                    if rpt
                        return
                    if not RegExMatch(action, "i)^<repeat>$") {
                        w.winRepeatCount := cnt
                        w.winRepeat := Action
                    }
                }
                EmptyMem()
            }

            SetHotkey(key, label) {
                ;msgbox % This.win
                if Strlen(This.win) > 0 {
                    class := This.win
                    Hotkey, IfWinActive, ahk_class %class%
                }
                else
                    Hotkey, IfWinActive

                mKey := ""
                Loop, Parse, Key
                {
                    if Asc(A_LoopField) >= 65 And Asc(A_LoopField) <= 90
                        mKey .= "<shift>" . Chr(Asc(A_LoopField)+32)
                    else
                        mKey .= A_LoopField
                }
                Hotkey_OK := True
                ;Idx := This.KeyList[0] ? This.KeyList[0] : 1
                cnt := 1
                _SaveList := []
                for, i, k in This.ResolveHotkey(mKey)
                {
                    Hotkey, %k%, <HotkeyLabel>, On, UseErrorLevel
                    if ErrorLevel
                    {
                        Msgbox 映射错误
                        Hotkey_OK := False
                        Break
                    }
                    ;if Not This.KeyList[k] {
                    ;    This.KeyList[idx] := k
                    ;    idx++
                    ;}
                    _SaveList[cnt] := k
                    cnt++
                    This.KeyList[k] := This.KeyList[k] ? This.KeyList[k] + 1 : 1
                }
                ;This.KeyList[0] := idx
                if Not Hotkey_OK {
                    For i , k IN _SaveList
                    {
                        This.KeyList[k] := This.KeyList[k] - 1
                        if This.KeyList[k] = 0 {
                            Hotkey, %k%, off
                        }
                    }
                }
                else {
                    This.KeyBody[mkey] := label
                    if not RegExMatch(This.KeyString, "\t" This.ToMatch(mKey) "[^\t]*")
                        This.KeyString .= A_Tab mKey A_Tab
                }
            }

            ResolveHotkey(KeyList)
            {
                Keys := []
                NewKeyList := []
                n := 1
                Loop
                {
                    Pos := RegExMatch(KeyList, "<[^<>]*>", A_Index)
                    if Pos
                    {
                        LoopKey := SubStr(KeyList, 1, Pos-1)
                        Loop, Parse, LoopKey
                        {
                            if Asc(A_LoopField) >= 65 And Asc(A_LoopField) <= 90
                            {
                                Keys[n] := "shift"
                                n++
                                Keys[n] := Chr(Asc(A_LoopField)+32)
                            }
                            else
                                Keys[n] := A_LoopField
                            n++
                        }
                        KeyList := SubStr(KeyList, Pos, Strlen(KeyList))
                        Pos := RegExMatch(KeyList, ">")
                        Keys[n] := SubStr(KeyList, 2, Pos-2)
                        KeyList := SubStr(KeyList, Pos+1, Strlen(KeyList))
                        n++
                    }
                    else
                    {
                        Loop, Parse, KeyList
                        {
                            if Asc(A_LoopField) >= 65 And Asc(A_LoopField) <= 90
                            {
                                Keys[n] := "shift"
                                n++
                                Keys[n] := Chr(Asc(A_LoopField)+32)
                            }
                            else
                                Keys[n] := A_LoopField
                            n++
                        }
                        Break
                    }
                }
                n := 1
                For, i, key in Keys
                {
                    if RegExMatch(key, "i)(l|r)?(ctrl|shift|win|alt)")
                    {
                        List .= Key " & "
                        Continue
                    }
                    else
                    {
                        List .= Key
                        NewKeyList[n] := List
                        List :=
                    }
                    n++
                }
                Return NewKeyList
            }

            GetThisHotkey(G_ThisHotkey = "")
            {
                if Strlen(G_ThisHotkey) = 0
                    G_ThisHotkey := A_ThisHotkey
                GetKeyState, Var, CapsLock, T
                if Var = D
                {
                    if RegExMatch(ThisHotkey, "i)^(l|r)?shift\s&\s[a-z]$")
                        ThisHotkey := Substr(ThisHotkey, 0)
                    else if RegExMatch(G_ThisHotkey, "^[a-z]$")
                        ThisHotkey := "shift & " . G_ThisHotkey
                    else
                        ThisHotkey := A_ThisHotkey
                }
                else
                    ThisHotkey := G_ThisHotkey
                Loop
                {
                    if RegExMatch(ThisHotkey, "(?<!<)(((l|r)?(ctrl|control|alt|win|shift))|(f\d\d?)|esc|escape|space|tab|enter|bs|del|ins|home|end|pgup|pgdn|up|down|left|right|((?<=&\s)[<>]$))(?!>)", m) {
                        ThisHotkey := RegExReplace(ThisHotkey, This.ToMatch(m), "<" m ">")
                    }
                    else
                    {
                        ThisHotkey := RegExReplace(ThisHotkey, "\s&\s")
                        Break
                    }
                }
                ;msgbox % Thishotkey
                Return ThisHotKey
            }

            ; TransSendKey(hotkey) {{{2
            ; 在SendKey时，将hotkey转换为Send能支持的格式
            TransSendKey(hotkey)
            {
                Loop
                {
                    if RegExMatch(Hotkey, "i)^(f\d\d?)|esc|escpa|space|tab|enter|bs|del|ins|home|end|pgup|pgdn|up|down|left|right|!|#|\+|\^|\{|\}$")
                    {
                        Hotkey := "{" . Hotkey . "}"
                        Break
                    }
                    if StrLen(hotkey) > 1 AND Not RegExMatch(Hotkey, "^\+.$")
                    {
                        Hotkey := "{" . hotkey . "}"
                        if RegExMatch(hotkey, "i)(shift|lshift|rshift)(\s\&\s)?.+$")
                            Hotkey := "+" . RegExReplace(hotkey, "i)(shift|lshift|rshift)(\s\&\s)?")
                        if RegExMatch(hotkey, "i)(ctrl|lctrl|rctrl|control|lcontrol|rcontrol)(\s\&\s)?.+$")
                            Hotkey := "^" . RegExReplace(hotkey, "i)(ctrl|lctrl|rctrl|control|lcontrol|rcontrol)(\s\&\s)?")
                        if RegExMatch(hotkey, "i)(lwin|rwin)(\s\&\s)?.+$")
                            Hotkey := "#" . RegExReplace(hotkey, "i)(lwin|rwin)(\s\&\s)?")
                        if RegExMatch(hotkey, "i)(alt|lalt|ralt)(\s\&\s)?.+$")
                            Hotkey := "!" . RegExReplace(hotkey, "i)(alt|lalt|ralt)(\s\&\s)?")A
                    }
                    if RegExMatch(Hotkey, "^\+.$")
                    {
                        Hotkey := SubStr(Hotkey, 1, 1) . "{" . SubStr(Hotkey, 2) . "}"
                    }
                    GetKeyState, Var, CapsLock, T
                    if Var = D
                    {
                        if RegExMatch(Hotkey, "^\+\{[a-z]\}$")
                        {
                            Hotkey := SubStr(Hotkey, 2)
                            Break
                        }
                        if RegExMatch(Hotkey, "^[a-z]$")
                        {
                            Hotkey := "+{" . Hotkey . "}"
                            Break
                        }
                        if RegExMatch(Hotkey, "^\{[a-z]\}$")
                        {
                            Hotkey := "+" . Hotkey
                            Break
                        }
                    }
                    Break
                }
                Return hotkey
            }

            ToMatch(Key)
            {
                Key := RegExReplace(Key, "\+|\?|\.|\*|\{|\}|\(|\)|\||\^|\$|\[|\]|\\", "\$0")
                Return RegExReplace(Key, "\s", "\s")
            }

        }
    }

}

SetTimeOutClass(win) {
    vim.TimeOutClass := win
}
GetTimeOutClass(win) {
    w := vim.Vaild(win)
    return w.TimeOut
}
GetCommentDest(action) {
    Return vim.CommentList[action]
}
GetCommentType(action) {
    Type := vim.CommentType[action]
    if Strlen(Type)
        return Type
    else
        return true
}
EmptyMem(PID = "AHK Rocks")
{
    pid := (pid = "AHK Rocks") ? DllCall("GetCurrentProcessId") : pid
    h := DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
    DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
    DllCall("CloseHandle", "Int", h)
}
<TimeOutLabel>:
    vim.TimeOut()
return

<HotkeyLabel>:
    vim.Do()
return

<Repeat>:
    vim.Repeat()
return

/*
API 函数列表：
vim.mode("模式", "ahk_class")  ; 设置运行的模式
vim.map("热键", "Label标签", "ahk_class")  ;映射热键
vim.settimeout("按键超时时间", "ahk_class")  ;设置按键超时时间
vim.listkey("ahk_class")  ;显示所有映射的热键体
vim.control("on/off", "ahk_class")  ;启用/禁用映射的热键
vim.comment("标签", "描述", "是否允许多次运行（0/1)")
内置Label:
<Repeat> 重复上一次动作
*/

#UseHook On
Setkeydelay, -1
return

; 此函数可以根据自己的喜好进行修改
ShowComment(more="") {
    if not ToShowComment
        return

    WinGetClass, win, A
    w := vim.Vaild(win)
    mode := w.GetMode()
    msg := mode.KeyTemp "`n=============================`n"
    ;GUIControl, , Edit1, %msg%

    if Strlen(more)
    {
        Loop, Parse, more, `n
        {
            key := Trim(A_LoopField)
            action := mode.KeyBody[key]
            ;comment := vim.CommentList[action]
            comment := GetCommentDest(action)
            if Strlen(comment)
                msg .= key "  >>  " comment "`n"
            else
                msg .= key "  >>  " action "`n"

        }
        Tooltip % msg
        ;GUI, VIMINFO:Show
    }
    else
        Tooltip
        ;GUI, VIMINFO:Show, Hide
}

; ====================
; ====================
; 内部脚本，请匆修改！
; ====================
; ====================

; 初始化 vimcore
Init() {
    OnMessage(0x05, "GuiSize")
    GoSub, vimnew
}

vimnew:
    Global vim := new vimcore
return

; 以下为class封装，请匆修改
Class vimcore {
    __New() {
       This.vimWindows := []
       This.vimGlobal  := new This.vimClass("")
       This.TimeOutClass := ""
       This.ExcludeList := []
       ;This.ExcludeList["AutoHotkey"] := True
       This.CommentList := []
       This.CommentType := []
       This.UseHotkey   := []
    }

    Vaild(win) {
        if Strlen(win) = 0
            Return This.vimGlobal
        w := This.vimWindows[win]
        if w.winVaild
            return w
        else
            return This.vimGlobal
    }

    mode(mode, win="") {
        if Strlen(win) = 0
            w := This.vimGlobal
        else
            w := This.vimWindows[win]
        if not w.winVaild
        {
            w := new This.vimClass(win)
            This.vimWindows[win] := w
        }
        w.SetMode(mode)
        ShowComment()
    }

    sMap(key, label, win=""){
        This.UseHotkey[key] := True
        this.Map(key, label, win)
    }

    Map(key, label, win="") {
        if not RegExMatch(Key, "[^\s]")
            return
        if Strlen(win) = 0
            w := This.vimGlobal
        else
            w := This.vimWindows[win]
        if not w.winVaild
        {
            w := new This.vimClass(win)
            This.vimWindows[win] := w
        }
        mode := w.GetMode()
        mode.SetHotkey(key, label)
    }

    Comment(action, desc, complex=1) {
        This.CommentList[action] := desc
        This.CommentType[action] := complex
    }

    do() {
        WinGetClass, win, A
        w := This.Vaild(win)
        m := w.GetMode()
        if This.ExcludeList[win] And not this.UseHotkey[m.GetThisHotkey()]
        {
            Send, % m.TransSendKey(A_ThisHotkey)
            return
        }
        if w.winVaild {
            mode := w.GetMode()
            if Mode.KeyList[A_ThisHotkey]
                mode.Try()
            else
            {
                w := This.vimGlobal
                mode := w.GetMode()
                mode.Try()
            }
        }
    }

    Filter(String) {

        WinGetClass, win, A

        if This.ExcludeList[win]
            return
        w := This.Vaild(win)

        if w.winVaild {
            mode := w.GetMode()
            mode.query(string)
        }
    }

    Exclude(win) {
        This.ExcludeList[win] := True
    }

    Include(win) {
        This.ExcludeList[win] := False
    }

    ListKey(win="", mode="") {
        w := This.Vaild(win)
        if strlen(mode) {
            m := w.winmode[mode]
            For k , l in m.KeyBody
                msg .= k "  " l "`n"
            return msg
        }
        else {
            For n , m  in w.winMode
            {
                msg .= "====`n" n "`n----`n"
                mode := m
                For k , l in m.KeyBody
                    msg .= k "  " l "`n"
            }
            return msg
        }
    }

    copy(win1, win2) {

        w2 := This.vimWindows[win2]

        if w2.winVaild
            return False

        w1 := This.Vaild(win1)
        w1.winName := win2
        For n , m in w1.WinMode
        {
            mode := m
            mode.win := win2
            w1.WinMode[n] := mode
            For k , l in m.KeyList
            {
                Hotkey, IfWinActive, ahk_class %win2%
                Hotkey, %k%, <HotkeyLabel>
            }
        }
        This.vimWindows[win2] := w1
        return True
    }

    CopyMode(win, mode, to) {
        w := This.Vaild(win)
        if strlen(mode) = 0
            return

        vim.mode(to, win)
        m := w.winmode[mode]
        For k , l in m.KeyBody
            vim.map(k, l, win)
    }

    Control(switch, win="") {
        w := This.Vaild(win)
        if switch = on
        {
            For n , m  in w.winMode
            {
                mode := m
                For k , l in m.KeyList
                {
                    Hotkey, %k%, on
                }
            }
        }
        if switch = off
        {
            For n , m  in w.winMode
            {
                mode := m
                For k , l in m.KeyList
                {
                    Hotkey, %k%, off
                }
            }
        }
    }

    test() {
        msgbox vim test
    }

    SetTimeOut(tick, win="") {
        w := This.Vaild(win)
        if not w.winVaild
        {
            w := new This.vimClass(win)
            This.vimWindows[win] := w
        }
        w.TimeOut := tick
    }

    TimeOut() {
        w := This.Vaild(This.TimeOutClass)
        mode := w.GetMode()
        mode.KeyTemp := ""
        ;GoSub, % mode.TimeOutAction
        mode.ExecSub(mode.TimeOutAction)
        ;    ShowComment()
        mode.TimeOutAction := ""
    }

    Repeat() {
        WinGetClass, win, A
        w := This.vimWindows[win]
        if not w.winVaild
            w := This.vimGlobal
        if w.winVaild {
            mode := w.GetMode()
            mode.KeyCount := w.winRepeatCount
            mode.ExecSub(w.winRepeat, Ture)
        }
    }

    GetWin() {
        WinGetClass, win, A
        Return This.Vaild(win)
    }

    GetCount() {
        w := This.GetWin()
        m := w.GetMode()
        Return m.KeyCount ? m.KeyCount : 1
    }

    Class vimClass {

        __New(win) {
            This.winName := win
            This.winVaild   := 1
            This.winControl := 0
            This.winTimeOut := 0
            THis.winMaxCount := 99
            This.winKeyList := []
            This.winMode    := []
            This.winThisMode := ""
            This.winRepeat   := ""
            This.winRepeatCount := 0
        }
        ;设置窗口类下的模式
        SetMode(md) {
            m := This.winMode[md]
            if Strlen(m.Mode) = 0 {
                This.winThisMode := md
                m := new This.Mode(md, This.winName)
                This.winMode[md] := m
            }
            else
                This.winThisMode := md
            return m
        }
        ;获取窗口类下的模式

        GetMode() {
            m := This.winMode[This.winThisMode]
            return m
        }

        Class Mode {
            __New(mode, win) {
                This.Mode := mode
                This.win  := win ;可变
                if Strlen(win)
                    This.CheckMode := win "_CheckMode"
                else
                    This.CheckMode := "CheckMode"
                This.KeyTemp   := ""
                This.KeyString := ""
                This.KeyCount := 0
                This.TimeOut := 0
                This.TimeOutTick   := 0
                This.TimeOutAction := ""
                This.KeyBody := []
                This.KeyList := []
                This.KeyMap  := []
            }

            test() {
                msgbox % This.Mode
            }

            Try(){
                checkMode := This.CheckMode
                settimer, <TimeOutLabel>, off
                Key := This.GetThisHotkey()
                if ( Not This.KeyList[A_ThisHotkey] ) or ( IsFunc(CheckMode) AND (%CheckMode%()) ) {
                    Send, % This.TransSendKey(A_ThisHotkey)
                    ShowComment()
                    return
                }
                _SaveKeyTemp := This.KeyTemp
                This.KeyTemp .= Key
                P := 1
                more := ""
                moreCount := 0
                Loop {
                    P := RegExMatch(This.KeyString, "i)\t" This.ToMatch(This.keyTemp) "[^\t]*", m, P)
                    if P {
                        ;msgbox % This.KeyString "`np=" p "`nm=" m
                        more .= m "`n"
                        P += Strlen(m)
                        moreCount++
                    }
                    else
                        Break
                }
                more := RTrim(more, "`n")
                if moreCount = 0
                {
                    This.KeyTemp := ""

                    action := This.KeyBody[_SaveKeyTemp]
                    if Strlen(action) {
                        This.ExecSub(Action)
                    }
                    else {
                        action := This.KeyBody[Key]
                        if Strlen(action) {
                            if InvalidMode
                                ShowComment()
                            else
                                This.ExecSub(Action)
                        }
                        else {
                            if RegExMatch(This.KeyString, "i)\t" This.ToMatch(key) "[^\t]*")
                            {
                                if InvalidMode
                                    ShowComment()
                                else
                                    This.Try()
                            }
                            else
                            {
                                Send, % This.TransSendKey(A_ThisHotkey)
                                ShowComment()
                            }
                            return
                        }
                    }
                }
                else if moreCount = 1
                {
                    Action := This.KeyBody[This.KeyTemp]
                    if Strlen(Action) {
                        This.ExecSub(Action)
                        This.KeyTemp := ""
                    }
                    else
                        ShowComment(more)
                }
                else
                {
                    TimeOut := 0 - GetTimeOutClass(This.win)
                    if Timeout And This.KeyBody[This.KeyTemp]{
                        This.TimeOutAction := This.KeyBody[This.KeyTemp]
                        This.TimeOutTick   := A_TickCount
                        SetTimeOutClass(This.win)
                        Settimer, <TimeOutLabel>, %TimeOut%
                    }
                    ErrorLevel := True
                    ShowComment(more)
                    return more
                }
            }

            ExecSub(action) {
                w := vim.vaild(This.win)
                if RegExMatch(Action, "(?<=^<)\d(?=>$)", cnt) {
                        This.KeyCount := This.KeyCount * 10 + cnt
                        MaxCount := w.winMaxCount
                        if This.KeyCount > MaxCount
                            This.KeyCount := MaxCount
                        Tooltip % This.KeyCount
                        return false
                }
                else {
                    ShowComment()
                    if This.KeyCount And GetCommentType(Action)
                        cnt := This.KeyCount
                    else
                        cnt := 1
                    ;cnt := This.KeyCount ? This.KeyCount : 1
                    if RegExMatch(action, "^<.*>$") {
                        if IsLabel(action) {
                            Loop, %cnt%
                                GoSub % Action
                        }
                        else {
                            Msgbox %Action%不存在，请检查脚本
                            Return
                        }
                    }
                    if RegExMatch(action, "^\(.*\)$") {
                        file := SubStr(action, 2, Strlen(action)-2)
                        Run, %File%, , UseErrorLevel, ExecID
                        if ErrorLevel
                        {
                            msgbox 运行%file%失败
                            return
                        }
                        else
                        {
                            WinWait, AHK_PID %ExecID%, , 1
                            WinActivate, AHK_PID %ExecID%
                        }
                    }
                    if RegExMatch(Action, "^\{.*\}$") {
                        Text := Substr(Action, 2, Strlen(Action)-2)
                        Loop, %cnt%
                            Send, %Text%
                    }

                    This.KeyCount := 0
                    if rpt
                        return
                    if not RegExMatch(action, "i)^<repeat>$") {
                        w.winRepeatCount := cnt
                        w.winRepeat := Action
                    }
                }
                EmptyMem()
            }

            SetHotkey(key, label) {
                ;msgbox % This.win
                if Strlen(This.win) > 0 {
                    class := This.win
                    Hotkey, IfWinActive, ahk_class %class%
                }
                else
                    Hotkey, IfWinActive

                mKey := ""
                Loop, Parse, Key
                {
                    if Asc(A_LoopField) >= 65 And Asc(A_LoopField) <= 90
                        mKey .= "<shift>" . Chr(Asc(A_LoopField)+32)
                    else
                        mKey .= A_LoopField
                }
                Hotkey_OK := True
                ;Idx := This.KeyList[0] ? This.KeyList[0] : 1
                cnt := 1
                _SaveList := []
                for, i, k in This.ResolveHotkey(mKey)
                {
                    Hotkey, %k%, <HotkeyLabel>, On, UseErrorLevel
                    if ErrorLevel
                    {
                        Msgbox 映射错误
                        Hotkey_OK := False
                        Break
                    }
                    ;if Not This.KeyList[k] {
                    ;    This.KeyList[idx] := k
                    ;    idx++
                    ;}
                    _SaveList[cnt] := k
                    cnt++
                    This.KeyList[k] := This.KeyList[k] ? This.KeyList[k] + 1 : 1
                }
                ;This.KeyList[0] := idx
                if Not Hotkey_OK {
                    For i , k IN _SaveList
                    {
                        This.KeyList[k] := This.KeyList[k] - 1
                        if This.KeyList[k] = 0 {
                            Hotkey, %k%, off
                        }
                    }
                }
                else {
                    This.KeyBody[mkey] := label
                    if not RegExMatch(This.KeyString, "\t" This.ToMatch(mKey) "[^\t]*")
                        This.KeyString .= A_Tab mKey A_Tab
                }
            }

            ResolveHotkey(KeyList)
            {
                Keys := []
                NewKeyList := []
                n := 1
                Loop
                {
                    Pos := RegExMatch(KeyList, "<[^<>]*>", A_Index)
                    if Pos
                    {
                        LoopKey := SubStr(KeyList, 1, Pos-1)
                        Loop, Parse, LoopKey
                        {
                            if Asc(A_LoopField) >= 65 And Asc(A_LoopField) <= 90
                            {
                                Keys[n] := "shift"
                                n++
                                Keys[n] := Chr(Asc(A_LoopField)+32)
                            }
                            else
                                Keys[n] := A_LoopField
                            n++
                        }
                        KeyList := SubStr(KeyList, Pos, Strlen(KeyList))
                        Pos := RegExMatch(KeyList, ">")
                        Keys[n] := SubStr(KeyList, 2, Pos-2)
                        KeyList := SubStr(KeyList, Pos+1, Strlen(KeyList))
                        n++
                    }
                    else
                    {
                        Loop, Parse, KeyList
                        {
                            if Asc(A_LoopField) >= 65 And Asc(A_LoopField) <= 90
                            {
                                Keys[n] := "shift"
                                n++
                                Keys[n] := Chr(Asc(A_LoopField)+32)
                            }
                            else
                                Keys[n] := A_LoopField
                            n++
                        }
                        Break
                    }
                }
                n := 1
                For, i, key in Keys
                {
                    if RegExMatch(key, "i)(l|r)?(ctrl|shift|win|alt)")
                    {
                        List .= Key " & "
                        Continue
                    }
                    else
                    {
                        List .= Key
                        NewKeyList[n] := List
                        List :=
                    }
                    n++
                }
                Return NewKeyList
            }

            GetThisHotkey(G_ThisHotkey="")
            {
                if Strlen(G_ThisHotkey) = 0
                    G_ThisHotkey := A_ThisHotkey
                GetKeyState, Var, CapsLock, T
                if Var = D
                {
                    if RegExMatch(ThisHotkey, "i)^(l|r)?shift\s&\s[a-z]$")
                        ThisHotkey := Substr(ThisHotkey, 0)
                    else if RegExMatch(G_ThisHotkey, "^[a-z]$")
                        ThisHotkey := "shift & " . G_ThisHotkey
                    else
                        ThisHotkey := A_ThisHotkey
                }
                else
                    ThisHotkey := G_ThisHotkey
                Loop
                {
                    if RegExMatch(ThisHotkey, "(?<!<)(((l|r)?(ctrl|control|alt|win|shift))|(f\d\d?)|esc|escape|space|tab|enter|bs|del|ins|home|end|pgup|pgdn|up|down|left|right|((?<=&\s)[<>]$))(?!>)", m) {
                        ThisHotkey := RegExReplace(ThisHotkey, This.ToMatch(m), "<" m ">")
                    }
                    else
                    {
                        ThisHotkey := RegExReplace(ThisHotkey, "\s&\s")
                        Break
                    }
                }
                ;msgbox % Thishotkey
                Return ThisHotKey
            }

            ; TransSendKey(hotkey) {{{2
            ; 在SendKey时，将hotkey转换为Send能支持的格式
            TransSendKey(hotkey)
            {
                Loop
                {
                    if RegExMatch(Hotkey, "i)^(f\d\d?)|esc|escpa|space|tab|enter|bs|del|ins|home|end|pgup|pgdn|up|down|left|right|!|#|\+|\^|\{|\}$")
                    {
                        Hotkey := "{" . Hotkey . "}"
                        Break
                    }
                    if StrLen(hotkey) > 1 AND Not RegExMatch(Hotkey, "^\+.$")
                    {
                        Hotkey := "{" . hotkey . "}"
                        if RegExMatch(hotkey, "i)(shift|lshift|rshift)(\s\&\s)?.+$")
                            Hotkey := "+" . RegExReplace(hotkey, "i)(shift|lshift|rshift)(\s\&\s)?")
                        if RegExMatch(hotkey, "i)(ctrl|lctrl|rctrl|control|lcontrol|rcontrol)(\s\&\s)?.+$")
                            Hotkey := "^" . RegExReplace(hotkey, "i)(ctrl|lctrl|rctrl|control|lcontrol|rcontrol)(\s\&\s)?")
                        if RegExMatch(hotkey, "i)(lwin|rwin)(\s\&\s)?.+$")
                            Hotkey := "#" . RegExReplace(hotkey, "i)(lwin|rwin)(\s\&\s)?")
                        if RegExMatch(hotkey, "i)(alt|lalt|ralt)(\s\&\s)?.+$")
                            Hotkey := "!" . RegExReplace(hotkey, "i)(alt|lalt|ralt)(\s\&\s)?")A
                    }
                    if RegExMatch(Hotkey, "^\+.$")
                    {
                        Hotkey := SubStr(Hotkey, 1, 1) . "{" . SubStr(Hotkey, 2) . "}"
                    }
                    GetKeyState, Var, CapsLock, T
                    if Var = D
                    {
                        if RegExMatch(Hotkey, "^\+\{[a-z]\}$")
                        {
                            Hotkey := SubStr(Hotkey, 2)
                            Break
                        }
                        if RegExMatch(Hotkey, "^[a-z]$")
                        {
                            Hotkey := "+{" . Hotkey . "}"
                            Break
                        }
                        if RegExMatch(Hotkey, "^\{[a-z]\}$")
                        {
                            Hotkey := "+" . Hotkey
                            Break
                        }
                    }
                    Break
                }
                Return hotkey
            }

            ToMatch(Key)
            {
                Key := RegExReplace(Key, "\+|\?|\.|\*|\{|\}|\(|\)|\||\^|\$|\[|\]|\\", "\$0")
                Return RegExReplace(Key, "\s", "\s")
            }

        }
    }

}

SetTimeOutClass(win) {
    vim.TimeOutClass := win
}
GetTimeOutClass(win) {
    w := vim.Vaild(win)
    return w.TimeOut
}
GetCommentDest(action) {
    Return vim.CommentList[action]
}
GetCommentType(action) {
    Type := vim.CommentType[action]
    if Strlen(Type)
        return Type
    else
        return true
}
EmptyMem(PID="AHK Rocks")
{
    pid:=(pid="AHK Rocks") ? DllCall("GetCurrentProcessId") : pid
    h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
    DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
    DllCall("CloseHandle", "Int", h)
}
<TimeOutLabel>:
    vim.TimeOut()
return

<HotkeyLabel>:
    vim.Do()
return

<Repeat>:
    vim.Repeat()
return