├── History.md ├── Lib ├── Acc.ahk ├── GDIP.ahk ├── VIMD_Plugins.ahk ├── Yaml.ahk ├── class_EasyIni.ahk ├── class_vim.ahk └── dock.ahk ├── Plugins ├── everything │ └── everything.ahk ├── general │ └── general.ahk ├── totalcmd │ ├── a-zhistory.icl │ ├── totalcmd.ahk │ ├── totalcmd.ini │ └── totalcommander.ahk └── vimconfig │ └── vimconfig.ahk ├── README.md ├── check.ahk ├── example.ahk ├── viatc.ico ├── vimd.ini └── vimdesktop.ahk /History.md: -------------------------------------------------------------------------------- 1 | ## 计划完成的功能 2 | 3 | - [ ] 1. 增加Dock支持 4 | 5 | - [ ] 2. 增加一个简单的配置界面 6 | 7 | - [ ] 3. 迁移TC插件 8 | 9 | - [x] 4. 迁移Everything插件 10 | 11 | ## 历史记录 12 | * 2015-02-09 13:31:45 13 | 14 | > ++ 增加[vim.SetModeFunction()](https://github.com/linxinhong/VimDesktop/wiki/API#setmodefunctionfuncmodenamewinname) 15 | 16 | > ++ 优化vim.Debug调试界面。 17 | 18 | > ++ 优化判断逻辑。 19 | 20 | > ++ 增加 \ 独立搜索界面、\ 切换到桌面两个功能。 21 | 22 | > ++ 增加check.ahk用于检测管理插件,增加viatc.ico做为VIMD的图标。 23 | 24 | > ** 修复TC插件对totalcmd64.exe识别出错的问题。 25 | 26 | > ** 修复任务栏图标右键无法退出的Bug。 27 | 28 | > -- 移动 Plugins\Plugins.ahk到lib\vimd_plugins.ahk,便于管理。 29 | 30 | > ** 其它若干Bug修复。 31 | 32 | * 2015-02-07 17:49:20 33 | 34 | > ++ 增加对老版本的vimd插件的支持(可以直接迁移) 35 | 36 | > ++ 增加在映射的热键的时候,Action无效的错误处理(直接添加vim.SetAction)。 37 | 38 | > ** 修复无法复制Genral模式的问题 39 | 40 | > ** 其它若干Bug处理 41 | 42 | * 2015-02-07 10:50:44 43 | 44 | > ** 修复CapsLock判断的错误 45 | 46 | > ** 修复class_vim 的几个逻辑错误 47 | 48 | 49 | * 2015-02-05 16:44:11 50 | 51 | > ** 修复增加新特性后,TC插件无法使用的BUG 52 | 53 | > ** 修复TC64位与32位不正确的BUG 54 | 55 | > ** 修复按下[Count]后,不执行afterActionDo对应的函数 56 | 57 | 58 | * 2015-02-05 11:09:11 59 | 60 | > ++ 增加Example.ahk示例 61 | 62 | > ++ 增加SetWin时,使用ahk_exe判断,如: vim.setwin("记事本","Notepad","notepad.exe") 63 | 64 | > ** 修复vim.GetMore()不显示Count的Bug 65 | 66 | * 2015-02-03 67 | 68 | > 初始化 -------------------------------------------------------------------------------- /Lib/Acc.ahk: -------------------------------------------------------------------------------- 1 | ;------------------------------------------------------------------------------ 2 | ; Acc.ahk Standard Library 3 | ; by Sean 4 | ; Updated by jethrow: 5 | ; Modified ComObjEnwrap params from (9,pacc) --> (9,pacc,1) 6 | ; Changed ComObjUnwrap to ComObjValue in order to avoid AddRef (thanks fincs) 7 | ; Added Acc_GetRoleText & Acc_GetStateText 8 | ; Added additional functions - commented below 9 | ; Removed original Acc_Children function 10 | ; Added Acc_Error, Acc_ChildrenByRole, & Acc_Get functions 11 | ; last updated 10/25/2012 12 | ;------------------------------------------------------------------------------ 13 | 14 | Acc_Init() 15 | { 16 | Static h 17 | If Not h 18 | h:=DllCall("LoadLibrary","Str","oleacc","Ptr") 19 | } 20 | Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild) 21 | { 22 | Acc_Init() 23 | If DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0 24 | Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt") 25 | } 26 | 27 | Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") 28 | { 29 | Acc_Init() 30 | If DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0 31 | Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt") 32 | } 33 | 34 | Acc_ObjectFromWindow(hWnd, idObject = 0) 35 | { 36 | Acc_Init() 37 | If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0 38 | Return ComObjEnwrap(9,pacc,1) 39 | } 40 | 41 | Acc_WindowFromObject(pacc) 42 | { 43 | If DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0 44 | Return hWnd 45 | } 46 | 47 | Acc_GetRoleText(nRole) 48 | { 49 | nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0) 50 | VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize) 51 | DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1) 52 | Return sRole 53 | } 54 | 55 | Acc_GetStateText(nState) 56 | { 57 | nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0) 58 | VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize) 59 | DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1) 60 | Return sState 61 | } 62 | 63 | Acc_SetWinEventHook(eventMin, eventMax, pCallback) 64 | { 65 | Return DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0) 66 | } 67 | 68 | Acc_UnhookWinEvent(hHook) 69 | { 70 | Return DllCall("UnhookWinEvent", "Ptr", hHook) 71 | } 72 | /* Win Events: 73 | 74 | pCallback := RegisterCallback("WinEventProc") 75 | WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime) 76 | { 77 | Critical 78 | Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild) 79 | ; Code Here: 80 | 81 | } 82 | */ 83 | 84 | ; Written by jethrow 85 | Acc_Role(Acc, ChildId=0) { 86 | try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object" 87 | } 88 | Acc_State(Acc, ChildId=0) { 89 | try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object" 90 | } 91 | Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code 92 | try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId) 93 | catch 94 | return 95 | Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int") 96 | return {x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")} 97 | } 98 | Acc_Parent(Acc) { 99 | try parent:=Acc.accParent 100 | return parent?Acc_Query(parent): 101 | } 102 | Acc_Child(Acc, ChildId=0) { 103 | try child:=Acc.accChild(ChildId) 104 | return child?Acc_Query(child): 105 | } 106 | Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530 107 | try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1) 108 | } 109 | Acc_Error(p="") { 110 | static setting:=0 111 | return p=""?setting:setting:=p 112 | } 113 | Acc_Children(Acc) { 114 | if ComObjType(Acc,"Name") != "IAccessible" 115 | ErrorLevel := "Invalid IAccessible Object" 116 | else { 117 | Acc_Init(), cChildren:=Acc.accChildCount, Children:=[] 118 | if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 { 119 | Loop %cChildren% 120 | i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child): 121 | return Children.MaxIndex()?Children: 122 | } else 123 | ErrorLevel := "AccessibleChildren DllCall Failed" 124 | } 125 | if Acc_Error() 126 | throw Exception(ErrorLevel,-1) 127 | } 128 | Acc_ChildrenByRole(Acc, Role) { 129 | if ComObjType(Acc,"Name")!="IAccessible" 130 | ErrorLevel := "Invalid IAccessible Object" 131 | else { 132 | Acc_Init(), cChildren:=Acc.accChildCount, Children:=[] 133 | if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 { 134 | Loop %cChildren% { 135 | i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i) 136 | if NumGet(varChildren,i-8)=9 137 | AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild): 138 | else 139 | Acc_Role(Acc, child)=Role?Children.Insert(child): 140 | } 141 | return Children.MaxIndex()?Children:, ErrorLevel:=0 142 | } else 143 | ErrorLevel := "AccessibleChildren DllCall Failed" 144 | } 145 | if Acc_Error() 146 | throw Exception(ErrorLevel,-1) 147 | } 148 | Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") { 149 | static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"} 150 | AccObj := IsObject(WinTitle)? WinTitle 151 | : Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 ) 152 | if ComObjType(AccObj, "Name") != "IAccessible" 153 | ErrorLevel := "Could not access an IAccessible Object" 154 | else { 155 | StringReplace, ChildPath, ChildPath, _, %A_Space%, All 156 | AccError:=Acc_Error(), Acc_Error(true) 157 | Loop Parse, ChildPath, ., %A_Space% 158 | try { 159 | if A_LoopField is digit 160 | Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement 161 | else 162 | RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1) 163 | if Not Children.HasKey(m2) 164 | throw 165 | AccObj := Children[m2] 166 | } catch { 167 | ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError) 168 | if Acc_Error() 169 | throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField) 170 | return 171 | } 172 | Acc_Error(AccError) 173 | StringReplace, Cmd, Cmd, %A_Space%, , All 174 | properties.HasKey(Cmd)? Cmd:=properties[Cmd]: 175 | try { 176 | if (Cmd = "Location") 177 | AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId) 178 | , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int") 179 | else if (Cmd = "Object") 180 | ret_val := AccObj 181 | else if Cmd in Role,State 182 | ret_val := Acc_%Cmd%(AccObj, ChildID+0) 183 | else if Cmd in ChildCount,Selection,Focus 184 | ret_val := AccObj["acc" Cmd] 185 | else 186 | ret_val := AccObj["acc" Cmd](ChildID+0) 187 | } catch { 188 | ErrorLevel := """" Cmd """ Cmd Not Implemented" 189 | if Acc_Error() 190 | throw Exception("Cmd Not Implemented", -1, Cmd) 191 | return 192 | } 193 | return ret_val, ErrorLevel:=0 194 | } 195 | if Acc_Error() 196 | throw Exception(ErrorLevel,-1) 197 | } -------------------------------------------------------------------------------- /Lib/VIMD_Plugins.ahk: -------------------------------------------------------------------------------- 1 | #include *i %A_ScriptDir%\plugins\everything\everything.ahk 2 | #include *i %A_ScriptDir%\plugins\general\general.ahk 3 | #include *i %A_ScriptDir%\plugins\totalcmd\totalcmd.ahk 4 | #include *i %A_ScriptDir%\plugins\vimconfig\vimconfig.ahk 5 | /* 6 | [ExtensionsTime] 7 | everything=20150206102929 8 | general=20150207174327 9 | totalcmd=20150207115832 10 | vimconfig=20150106173600 11 | */ 12 | -------------------------------------------------------------------------------- /Lib/Yaml.ahk: -------------------------------------------------------------------------------- 1 | Yaml(YamlText,IsFile=1,YamlObj=0){ ; Version 1.0.0.13 http://www.autohotkey.com/forum/viewtopic.php?t=70559 2 | static 3 | static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} 4 | static BackupVars:="LVL,SEQ,KEY,SCA,TYP,VAL,CMT,LFL,CNT",IncompleteSeqMap 5 | local maxLVL:=0,LastContObj:=0,LastContKEY:=0,LinesAdded:=0,_LVLChanged:=0,_LVL,_SEQ,_KEY,_SCA,_TYP,_VAL,_CMT,_LFL,_CNT,_NXT,__LVL,__SEQ,__KEY,__SCA,__TYP,__VAL,__CMT,__LFL,__CNT,__NXT 6 | AutoTrim % ((AutoTrim:=A_AutoTrim)="On")?"Off":"Off" 7 | LVL0:=pYaml:=YamlObj?YamlObj:Object("base",base),__LVL:=0,__LVL0:=0 8 | If IsFile 9 | FileRead,YamlText,%YamlText% 10 | Loop,Parse,YamlText,`n,`r 11 | { 12 | If (!_CNT && (A_LoopField=""||RegExMatch(A_LoopField,"^\s+$"))){ ;&&__KEY=""&&__SEQ="")){ 13 | If ((OBJ:=LVL%__LVL%[""].MaxIndex())&&IsObject(LVL%__LVL%["",OBJ])&&__SEQ){ 14 | If (__KEY!="") 15 | Yaml_Continue(LastContObj:=LVL%__LVL%["",Obj],LastContKEY:=__key,"",__SCA) 16 | else Yaml_Continue(LastContObj:=LVL%__LVL%[""],LastContKEY:=Obj,"",__SCA,__SEQ) 17 | } else If (__SEQ && OBJ){ 18 | Yaml_Continue(LastContObj:=LVL%__LVL%[""],LastContKEY:=Obj,"",__SCA,__SEQ) 19 | } else If (OBJ){ 20 | Yaml_Continue(LastContObj:=LVL%__LVL%[""],LastContKEY:=OBJ,"",__SCA,1) 21 | } else if (__KEY!="") 22 | Yaml_Continue(LastContObj:=LVL%__LVL%,LastContKEY:=__KEY,"",__SCA) 23 | else LinesAdded-- 24 | LinesAdded++ 25 | Continue 26 | } else If (!_CNT && LastContObj 27 | && ( RegExMatch(A_LoopField,"^(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)") 28 | || RegExMatch(A_LoopField,"^(---)|\s*(-\s)") )){ 29 | If !__SCA 30 | LastContObj[LastContKEY]:=SubStr(LastContObj[LastContKEY],1,-1*LinesAdded) 31 | LastContObj:=0,LastContKEY:=0,LinesAdded:=0 32 | } 33 | If InStr(A_LoopField,"#"){ 34 | If (RegexMatch(A_LoopField,"^\s*#.*") || InStr(A_LoopField,"%YAML")=1) ;Comments only, do not parse 35 | continue 36 | else if Yaml_IsQuoted(LTrim(A_LoopField," -")) || RegExMatch(A_LoopField,"(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)\s*([\|\>][+-]?)?\s*(!!\w+\s)?\s*("".+|'.+)$")&&!RegExMatch(A_LoopField,"[^\\]""\s+#") 37 | LoopField:=A_LoopField 38 | else if RegExMatch(A_LoopField,"\s+#.*$","",RegExMatch(A_LoopField,"(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?\s*([\|\>][+-]?)?\s*(!!\w+\s)?\s*("".+""|'.+')?\K")-1) 39 | LoopField:=SubStr(A_LoopField,1,RegExMatch(A_LoopField,"\s+#.*$","",RegExMatch(A_LoopField,"(---)?\s*?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?\s*([\|\>][+-]?)?\s*(!!\w+\s)?\s*("".+""|'.+')?\K")-1)-1) 40 | else LoopField:=A_LoopField 41 | } else LoopField:=A_LoopField 42 | If _CNT { 43 | If Yaml_IsSeqMap(RegExReplace(IncompleteSeqMap LoopField,"^(\s+)?(-\s)?("".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?")) 44 | LoopField:=IncompleteSeqMap LoopField,_CNT:=0,IncompleteSeqMap:="" 45 | else { 46 | IncompleteSeqMap.=LoopField 47 | continue 48 | } 49 | } 50 | If (LoopField="---"){ 51 | Loop % (maxLVL) 52 | LVL%A_Index%:="" 53 | Loop,Parse,BackupVars,`, 54 | __%A_LoopField%:="",__%A_LoopField%0:="" 55 | Loop,Parse,BackupVars,`, 56 | Loop % maxLVL 57 | __%A_LoopField%%A_Index%:="" 58 | maxLVL:=0 59 | __LVL:=0,__LVL0:=0 60 | If !IsObject(pYaml[""]) 61 | pYaml[""]:=Object("base",base) 62 | pYaml[""].Insert(LVL0:=Object("base",base)) 63 | Continue 64 | } else if (LoopField="..."){ 65 | LVL0:=pYaml 66 | Loop % maxLVL 67 | LVL%A_Index%:="" 68 | Loop,Parse,BackupVars,`, 69 | __%A_LoopField%:="",__%A_LoopField%0:="" 70 | Loop,Parse,BackupVars,`, 71 | Loop % maxLVL 72 | __%A_LoopField%%A_Index%:="" 73 | maxLVL:=0 74 | __LVL:=0,__LVL0:=0 75 | Continue 76 | } 77 | If (SubStr(LoopField,0)=":") 78 | LoopField.=A_Space ; add space to force RegEx to match even if the value and space after collon is missing e.g. Object:`n objects item 79 | RegExMatch(LoopField,"^(?\s+)?(?-\s)?(?"".+""\s*:\s|'.+'\s*:\s|[^:""'\{\[]+\s*:\s)?\s*(?[\|\>][+-]?)?\s*(?!!\w+\s)?\s*(?"".+""|'.+'|.+)?\s*$",_) 80 | If _KEY ;cut off (:) 81 | StringTrimRight,_KEY,_KEY,2 82 | _KEY:=Yaml_UnQuoteIfNeed(_KEY) 83 | If IsVal:=Yaml_IsQuoted(_VAL) 84 | _VAL:=Yaml_UnQuoteIfNeed(_VAL) 85 | ;determine current level 86 | _LVL:=Yaml_S2I(_LVL) 87 | If (_LVL-__LVL>(__SEQ?2:1) ||(_LVL>__LVL&&_LVLChanged)) ;&&!(__SEQ&&__KEY!=""&&_KEY!="")) 88 | _LVL:=__LVL+1+(__SEQ?1:0),_LVLChanged:=_LVL ;__LVL%_LVL%:=__LVL%_NXT% 89 | else if _LVLChanged 90 | _LVL:=_LVLChanged 91 | else _LVLChanged:=0 92 | If (maxLVL<_LVL) 93 | maxLVL:=_LVL+(_SEQ?1:0) 94 | ; Cut off the leading tabs/spaces conform _LVL 95 | SubStr:=0,Tabs:=0 96 | Loop,Parse,LoopField 97 | If (_LVL*2=SubStr || !SubStr:=SubStr+(A_LoopField=A_Tab?2:1)), Tabs:=Tabs+(A_LoopField=A_Tab?1:0) 98 | break 99 | _LFL:=SubStr(LoopField,SubStr-Tabs+1+(_SEQ?2:0)) 100 | _LFL:=Yaml_UnQuoteIfNeed(_LFL) 101 | _NXT:=_LVL+1 ;next indentation level 102 | __NXT:=_NXT+1 103 | _PRV:=_LVL=0?0:_LVL-1 104 | Loop,Parse,BackupVars,`, 105 | __%A_LoopField%:=__%A_LoopField%%_PRV% 106 | If RegExMatch(_LFL,"^-\s*$"){ 107 | _SEQ:="-",_KEY:="",_VAL:="" 108 | } 109 | If (!IsVal && !_CNT && (_CNT:=Yaml_Incomplete(Trim(_LFL))||Yaml_Incomplete(Trim(_VAL)))){ 110 | IncompleteSeqMap:=LoopField 111 | continue 112 | } 113 | If (_LVL<__LVL){ ;Reset Objects and Backup vars 114 | Loop % (maxLVL) 115 | If (A_Index>_LVL){ 116 | Loop,Parse,BackupVars,`, 117 | __%A_LoopField%%maxLVL%:="" 118 | LVL%A_Index%:="",maxLVL:=maxLVL-1 119 | } 120 | If (_LVL=0 && !__LVL:=__LVL0:=0) 121 | Loop,Parse,BackupVars,`, 122 | __%A_LoopField%:="",__%A_LoopField%0:="" 123 | } 124 | If (_SEQ&&_LVL>__LVL&&(__VAL!=""||__SCA)) 125 | _SEQ:="",_KEY:="",_VAL:="",_LFL:="- " _LFL 126 | If (__CNT)||(_LVL>__LVL&&(__KEY!=""&&_KEY="")&&(__VAL!=""||__SCA))||(__SEQ&&__SCA) 127 | _KEY:="",_VAL:="" 128 | If (__CNT||(_LVL>__LVL&&(__KEY!=""||(__SEQ&&(__LFL||__SCA)&&!Yaml_IsSeqMap(__LFL)))&&!(_SEQ||_KEY!=""))){ 129 | If ((OBJ:=LVL%__LVL%[""].MaxIndex())&&IsObject(LVL%__LVL%["",OBJ])&&__SEQ){ 130 | If __KEY!= 131 | Yaml_Continue(LVL%__LVL%["",Obj],__key,_LFL,__SCA),__CNT:=Yaml_SeqMap(LVL%__LVL%["",OBJ],__KEY,LVL%__LVL%["",OBJ,__KEY])?"":__CNT 132 | else Yaml_Continue(LVL%__LVL%[""],Obj,_LFL,__SCA,__SEQ),__CNT:=Yaml_SeqMap(LVL%__LVL%[""],OBJ,LVL%__LVL%["",OBJ],__SEQ)?"":__CNT 133 | } else If (__SEQ && OBJ){ 134 | Yaml_Continue(LVL%__LVL%[""],Obj,_LFL,__SCA,__SEQ) 135 | __CNT:=Yaml_SeqMap(LVL%__LVL%[""],OBJ,LVL%__LVL%["",OBJ],__SEQ)?"":__CNT 136 | } else If (OBJ && __KEY=""){ 137 | Yaml_Continue(LVL%__LVL%[""],OBJ,_LFL,__SCA,1) 138 | __CNT:=Yaml_SeqMap(LVL%__LVL%[""],OBJ,LVL%__LVL%["",OBJ],1)?"":__CNT 139 | } else { 140 | Yaml_Continue(LVL%__LVL%,__KEY,_LFL,__SCA) 141 | __CNT:=Yaml_SeqMap(LVL%__LVL%,__KEY,LVL%__LVL%[__KEY])?"":__CNT 142 | } 143 | Continue 144 | } 145 | ;Create sequence or map 146 | If (__SEQ&&(_LVL>__LVL)&&_KEY!=""&&__KEY!=""){ 147 | OBJ:=LVL%__LVL%[""].MaxIndex() 148 | If _SEQ { 149 | If !Yaml_SeqMap(LVL%_LVL%["",OBJ,__KEY,""],_KEY,_VAL){ 150 | If !IsObject(LVL%__LVL%["",OBJ,__KEY,""]) 151 | LVL%__LVL%["",OBJ,__KEY,""]:={base:base} 152 | LVL%__LVL%["",OBJ,__KEY,""].Insert({(_KEY):_VAL!=""?_VAL:(LVL%_NXT%:={base:base}),base:base}) 153 | } 154 | } else If !Yaml_SeqMap(LVL%_LVL%["",OBJ],_KEY,_VAL){ 155 | LVL%__LVL%["",OBJ,_KEY]:=_VAL!=""?_VAL:(LVL%_NXT%:={base:base}) 156 | } 157 | If _VAL!= 158 | continue 159 | } else If (_SEQ){ 160 | If !IsObject(LVL%_LVL%[""]) 161 | LVL%_LVL%[""]:=Object("base",base) 162 | While (SubStr(_LFL,1,2)="- "){ 163 | _LFL:=SubStr(_LFL,3),_KEY:=(_KEY!="")?_LFL:=SubStr(_KEY,3):_KEY,LVL%_LVL%[""].Insert(LVL%_NXT%:=Object("",Object("base",base),"base",base)),_LVL:=_LVL+1,_NXT:=_NXT+1,__NXT:=_NXT+1,_PRV:=_LVL-1,maxLVL:=(maxLVL<_LVL)?_LVL:maxLVL 164 | Loop,Parse,BackupVars,`, 165 | __%A_LoopField%:=_%A_LoopField% 166 | ,__%A_LoopField%%_PRV%:=_%A_LoopField% 167 | } 168 | If (_KEY="" && _VAL="" && !IsVal){ 169 | If !Yaml_SeqMap(LVL%_LVL%[""],"",_LFL) 170 | LVL%_LVL%[""].Insert(LVL%_NXT%:=Object("base",base)) 171 | } else If (_KEY!="") { 172 | LVL%_LVL%[""].Insert(LVL%__NXT%:=Object(_KEY,LVL%_NXT%:=Object("base",base),"base",base)) 173 | If !Yaml_SeqMap(LVL%__NXT%,_KEY,_VAL){ 174 | LVL%_LVL%[""].Remove() 175 | LVL%_LVL%[""].Insert(LVL%__NXT%:=Object(_KEY,(_VAL!=""||IsVal)?_VAL:LVL%_NXT%:=Object("base",base),"base",base)) 176 | } 177 | } else { 178 | If !Yaml_SeqMap(LVL%_LVL%[""],"",_LFL) 179 | LVL%_LVL%[""].Insert(_LFL) 180 | } 181 | If !LVL%_LVL%[""].MaxIndex() 182 | LVL%_LVL%.Remove("") 183 | } else if (_KEY!=""){ 184 | If (__SEQ) { 185 | If (OBJ:=LVL%_PRV%[""].MaxIndex())&&IsObject(LVL%_PRV%["",OBJ]){ 186 | If !Yaml_SeqMap(LVL%_PRV%["",OBJ],_KEY,_VAL) 187 | LVL%_PRV%["",OBJ,_KEY]:=(_VAL!=""||IsVal)?_VAL:(LVL%_NXT%:=Object("base",base)) 188 | } else { 189 | LVL%_PRV%[""].Insert(Object(_KEY,(_VAL!=""||IsVal)?_VAL:(LVL%_NXT%:=Object("base",base)),"base",base)) 190 | Yaml_SeqMap(LVL%_PRV%["",OBJ?OBJ+1:1],_KEY,_VAL) 191 | } 192 | } else 193 | If !Yaml_SeqMap(LVL%_LVL%,_KEY,_VAL) 194 | LVL%_LVL%[_KEY]:=_VAL!=""?_VAL:(LVL%_NXT%:=Object("base",base)) 195 | } else if (_LVL>__LVL && (__KEY!="")) { 196 | If (__VAL!="" || __SCA){ 197 | Yaml_Continue(LVL%__LVL%,__KEY,_LFL,__SCA) 198 | Yaml_SeqMap(LVL%__LVL%,__KEY,LVL%__LVL%[__KEY]) 199 | Continue 200 | } else { 201 | If !Yaml_SeqMap(LVL%__LVL%[__KEY],_KEY,_VAL) ;!!! no Scalar??? 202 | LVL%__LVL%[__KEY,_KEY]:=_VAL 203 | Continue 204 | } 205 | } else { 206 | If (_LVL>__LVL&&(OBJ:=LVL%__LVL%[""].MaxIndex())&&IsObject(LVL%__LVL%["",OBJ])&&__SEQ){ 207 | If __CNT 208 | Yaml_Continue(LVL%__LVL%[""],LVL%__LVL%[""].MaxIndex(),_LFL,__SCA,1) 209 | If (__CNT:=Yaml_SeqMap(LVL%__LVL%[""],"",_LFL)?"":1) 210 | LVL%__LVL%[""].Insert(_LFL) 211 | } else { 212 | If !IsObject(LVL%_LVL%[""]) 213 | LVL%_LVL%[""]:=Object("base",base) 214 | If __CNT 215 | Yaml_Continue(LVL%__LVL%[""],LVL%__LVL%[""].MaxIndex(),_LFL,__SCA,1) 216 | If (__CNT:=Yaml_SeqMap(LVL%_LVL%[""],"",_LFL)?"":1) 217 | LVL%_LVL%[""].Insert(_LFL) 218 | } 219 | Continue 220 | } 221 | Loop,Parse,BackupVars,`, 222 | __%A_LoopField%:=_%A_LoopField% 223 | ,__%A_LoopField%%_LVL%:=_%A_LoopField% 224 | } 225 | If (LastContObj && !__SCA) 226 | LastContObj[LastContKEY]:=SubStr(LastContObj[LastContKEY],1,-1*LinesAdded) 227 | AutoTrim %AutoTrim% 228 | Loop,Parse,BackupVars,`, 229 | If !(__%A_LoopField%:="") 230 | Loop % maxLVL 231 | __%A_LoopField%%A_Index%:="" 232 | Return pYaml,pYaml.base:=base 233 | } 234 | Yaml_Save(obj,file,level=""){ 235 | FileMove,% file,% file ".bakupyml",1 236 | FileAppend,% obj.Dump(),% file 237 | If !ErrorLevel 238 | FileDelete,% file ".bakupyml" 239 | else { 240 | FileMove,% file ".bakupyml",% file 241 | MsgBox,0, Error creating file, old file was restored. 242 | } 243 | } 244 | Yaml_Call(NotSupported,f,p*){ 245 | If (p.MaxIndex()>1){ 246 | Loop % p.MaxIndex() 247 | If A_Index>1 248 | f:=f[""][p[A_Index-1]] 249 | } 250 | Return (!p.MaxIndex()?f[""].MaxIndex():f[""][p[p.MaxIndex()]]) 251 | } 252 | Yaml_Merge(obj,merge){ 253 | for k,v in merge 254 | { 255 | If IsObject(v){ 256 | If obj.HasKey(k){ 257 | If IsObject(obj[k]) 258 | Yaml_Merge(obj[k],v) 259 | else obj[k]:=v 260 | } else obj[k]:=v 261 | } else obj[k]:=v 262 | } 263 | } 264 | Yaml_Add(O,Yaml="",IsFile=0){ 265 | static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} 266 | If Yaml_IsSeqMap(Trim(Yaml)){ 267 | If !IsObject(O[""]) 268 | O[""]:=Object("base",base) 269 | Yaml_SeqMap(O[""],"",Yaml) 270 | } else Yaml(Yaml,IsFile,O) 271 | } 272 | Yaml_Dump(O,J="",R=0,Q=0){ 273 | static M1:="{",M2:="}",S1:="[",S2:="]",N:="`n",C:=", ",S:="- ",E:="",K:=": " 274 | local dump:="",M,MX,F,I,key,value 275 | If (J=0&&!R) 276 | dump.= S1 277 | for key in O 278 | M:=A_Index 279 | If IsObject(O[""]){ 280 | M-- 281 | for key in O[""] 282 | MX:=A_Index 283 | If IsObject(O[""][""]) 284 | MX-- 285 | If O[""].MaxIndex() 286 | for key, value in O[""] 287 | { 288 | If key= 289 | continue 290 | I++ 291 | F:=IsObject(value)?(IsObject(value[""])?"S":"M"):E 292 | If (J!=""&&J<=R){ 293 | dump.=(F?(%F%1 Yaml_Dump(value,J,R+1,F) %F%2):Yaml_EscIfNeed(value)) (I=MX&&!M?E:C) ;(Q="S"&&I=1?S1:E)(Q="S"&&I=MX?S2:E) 294 | } else if F,dump:=dump N Yaml_I2S(R) S 295 | dump.= (J!=""&&J<=(R+1)?%F%1:E) Yaml_Dump(value,J,R+1,F) (J!=""&&J<=(R+1)?%F%2:E) 296 | else { 297 | ; If RegexMatch(value,"[\x{007F}-\x{FFFF}""\{\[']|:\s|\s#") 298 | dump .= Yaml_EscIfNeed(value) 299 | ; else { 300 | ; value:= (value=""?"''":RegExReplace(RegExReplace(Value,"m)^(.*[\r\n].*)$","|" (SubStr(value,-1)="`n`n"?"+":SubStr(value,0)=N?"":"-") "`n$1"),"ms)(*ANYCRLF)\R",N Yaml_I2S(R+1))) 301 | ; StringReplace,value,value,% N Yaml_I2S(R+1) N Yaml_I2S(R+1),% N Yaml_I2S(R+1),A 302 | ; dump.=value 303 | ; } 304 | } 305 | } 306 | } 307 | I=0 308 | for key, value in O 309 | { 310 | If key= 311 | continue 312 | I++ 313 | F:=IsObject(value)?(IsObject(value[""])?"S":"M"):E 314 | If (J=0&&!R) 315 | dump.= M1 316 | If (J!=""&&J<=R){ 317 | dump.=(Q="S"&&I=1?M1:E) Yaml_EscIfNeed(key) K 318 | dump.=F?(%F%1 Yaml_Dump(value,J,R+1,F) %F%2):Yaml_EscIfNeed(value) 319 | dump.=(Q="S"&&I=M?M2:E) (J!=0||R?(I=M?E:C):E) 320 | } else if F,dump:=dump N Yaml_I2S(R) Yaml_EscIfNeed(key) K 321 | dump.= (J!=""&&J<=(R+1)?%F%1:E) Yaml_Dump(value,J,R+1,F) (J!=""&&J<=(R+1)?%F%2:E) 322 | else { 323 | ; If RegexMatch(value,"[\x{007F}-\x{FFFF}""\{\['\t]|:\s|\s#") 324 | dump .= Yaml_EscIfNeed(value) 325 | ; else { 326 | ; value:= (value=""?"''":RegExReplace(RegExReplace(Value,"m)^(.*[\r\n].*)$","|" (SubStr(value,-1)="`n`n"?"+":SubStr(value,0)="`n"?"":"-") "`n$1"),"ms)(*ANYCRLF)\R","`n" Yaml_I2S(R+1))) 327 | ; StringReplace,value,value,% "`n" Yaml_I2S(R+1) "`n" Yaml_I2S(R+1),% "`n" Yaml_I2S(R+1),A 328 | ; dump.= value 329 | ; } 330 | } 331 | If (J=0&&!R){ 332 | dump.=M2 (I]")||RegExMatch(s,"m)\s$")||RegExMatch(s,"m)[\x{7F}-\x{7FFFFFFF}]") 413 | return ("""" . Yaml_CharUni(s) . """") 414 | else return s 415 | } 416 | Yaml_IsQuoted(ByRef s){ 417 | return InStr(".''."""".","." SubStr(Trim(s),1,1) SubStr(Trim(s),0) ".")?1:0 418 | } 419 | Yaml_UnQuoteIfNeed(s){ 420 | s:=Trim(s) 421 | If !(SubStr(s,1,1)=""""&&SubStr(s,0)="""") 422 | return (SubStr(s,1,1)="'"&&SubStr(s,0)="'")?SubStr(s,2,StrLen(s)-2):s 423 | else return Yaml_UniChar(SubStr(s,2,StrLen(s)-2)) 424 | } 425 | Yaml_S2I(str){ 426 | local idx:=0 427 | Loop,Parse,str 428 | If (A_LoopField=A_Tab) 429 | idx++ 430 | else if !Mod(A_index,2) 431 | idx++ 432 | Return idx 433 | } 434 | Yaml_I2S(idx){ 435 | Loop % idx 436 | str .= " " 437 | Return str 438 | } 439 | Yaml_Continue(Obj,key,value,scalar="",isval=0){ 440 | If !IsObject(isObj:=obj[key]) 441 | v:=IsObject(isObj)?"":isObj 442 | If scalar { 443 | StringTrimLeft,scaopt,scalar,1 444 | scalar:=Asc(scalar)=124?"`n":" " 445 | } else scalar:=" ",scaopt:="-" 446 | temp := (value=""?"`n":(SubStr(v,0)="`n"&&scalar="`n"?"":(v=""?"":scalar))) value (scaopt!="-"?(v&&value=""?"`n":""):"") 447 | obj[key]:=Yaml_UnQuoteIfNeed(v temp) 448 | } 449 | Yaml_Quote(ByRef L,F,Q,B,ByRef E){ 450 | Return (F="\"&&!E&&(E:=1))||(E&&!(E:=0)&&(L:=L ("\" F))) 451 | } 452 | Yaml_SeqMap(o,k,v,isVal=0){ 453 | v:=Trim(v,A_Tab A_Space "`n"),m:=SubStr(v,1,1) SubStr(v,0) 454 | If Yaml_IsSeqMap(v) 455 | return m="[]"?Yaml_Seq(o,k,SubStr(v,2,StrLen(v)-2),isVal):m="{}"?Yaml_Map(o,k,SubStr(v,2,StrLen(v)-2),isVal):0 456 | } 457 | Yaml_Seq(obj,key,value,isVal=0){ 458 | static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} 459 | ContinueNext:=0 460 | If (obj=""){ 461 | If (SubStr(value,0)!="]") 462 | Return 0 463 | else 464 | value:=SubStr(value,2,StrLen(value)-2) 465 | } else { 466 | If (key=""){ 467 | obj.Insert(Object("",cObj:=Object("base",base),"base",base)) 468 | } else if (isval && IsObject(obj[key,""])){ 469 | cObj:=obj[key,""] 470 | } else obj[key]:=Object("",cObj:=Object("base",base),"base",base) 471 | } 472 | Count:=StrLen(value) 473 | Loop,Parse,value 474 | { 475 | If ((Quote=""""&&Yaml_Quote(LF,A_LoopField,Quote,Bracket,Escape)) || (ContinueNext && !ContinueNext:=0)) 476 | Continue 477 | If (Quote){ 478 | If (A_LoopField=Quote){ 479 | Quote= 480 | If Bracket 481 | LF.= A_LoopField 482 | else LF:=SubStr(LF,2) 483 | Continue 484 | } 485 | LF .= A_LoopField 486 | continue 487 | } else if (!Quote&&InStr("""'",A_LoopField)){ 488 | Quote:=A_LoopField 489 | If !Bracket 490 | VQ:=Quote 491 | LF.=A_LoopField 492 | Continue 493 | } else if (!Quote&&Bracket){ 494 | If (Asc(A_LoopField)=Asc(Bracket)+2) 495 | BCount-- 496 | else if (A_LoopField=Bracket) 497 | BCount++ 498 | If (BCount=0) 499 | Bracket= 500 | LF .= A_LoopField 501 | Continue 502 | } else if (!Quote&&!Bracket&&InStr("[{",A_LoopField)){ 503 | Bracket:=A_LoopField 504 | BCount:=1 505 | LF.=A_LoopField 506 | Continue 507 | } 508 | If (A_Index=Count) 509 | LF .= A_LoopField 510 | else if (!Quote&&!Bracket&&A_LoopField=","&&(!InStr("0123456789",SubStr(value,A_Index-1,1)) | !InStr("0123456789",SubStr(value,A_Index+1,1)))){ 511 | ContinueNext:=SubStr(value,A_Index+1,1)=A_Space||SubStr(value,A_Index+1,1)=A_Tab 512 | LF:=LF 513 | } else { 514 | LF .= A_LoopField 515 | continue 516 | } 517 | If (obj=""){ 518 | If !VQ 519 | If (Asc(LF)=91 && !Yaml_Seq("","",LF)) 520 | ||(Asc(LF)=123 && !Yaml_Map("","",LF)) 521 | Return 0 522 | } else { 523 | If (VQ || !Yaml_SeqMap(cObj,"",LF)) 524 | cObj.Insert(VQ?Yaml_UniChar(LF):Trim(LF)) 525 | } 526 | LF:="",VQ:="" 527 | } 528 | If (LF){ 529 | If (obj=""){ 530 | If !VQ 531 | If (Asc(LF)=91 && !Yaml_Seq("","",LF))||(Asc(LF)=123 && !Yaml_Map("","",LF)) 532 | Return 0 533 | } else If (VQ || !Yaml_SeqMap(cObj,"",LF)) 534 | cObj.Insert(VQ?Yaml_UniChar(LF):Trim(LF)) 535 | } 536 | Return (obj=""?(Quote Bracket=""):1) 537 | } 538 | Yaml_Map(obj,key,value,isVal=0){ 539 | static base:={Dump:"Yaml_Dump",Save:"Yaml_Save",Add:"Yaml_Add",Merge:"Yaml_Merge",__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity",_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey",_Clone:"_Clone",Insert:"Insert",Remove:"Remove",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity",GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone",base:{__Call:"Yaml_Call"}} 540 | ContinueNext:=0 541 | If (obj=""){ 542 | If (SubStr(value,0)!="}") 543 | Return 0 544 | else 545 | value:=SubStr(value,2,StrLen(value)-2) 546 | } else { 547 | If (key="") 548 | obj.Insert(cObj:=Object("base",base)) 549 | else obj[key]:=(cObj:=Object("base",base)) 550 | } 551 | Count:=StrLen(value) 552 | Loop,Parse,value 553 | { 554 | 555 | If ((Quote=""""&&Yaml_Quote(LF,A_LoopField,Quote,Bracket,Escape)) || (ContinueNext && !ContinueNext:=0)) 556 | Continue 557 | If (Quote){ 558 | If (A_LoopField=Quote){ 559 | Quote= 560 | LF.=A_LoopField 561 | } else LF .= A_LoopField 562 | continue 563 | } else if (!Quote&&(k=""||v="")&&InStr("""'",A_LoopField)){ 564 | Quote:=A_LoopField 565 | If (k && !Bracket) 566 | VQ:=Quote 567 | else if !Bracket 568 | KQ:=Quote 569 | LF.=Quote 570 | Continue 571 | } else If (k!=""&&LF=""&&InStr("`n`r `t",A_LoopField)){ 572 | Continue 573 | } 574 | If (!Quote&&Bracket){ 575 | If (Asc(A_LoopField)=Asc(Bracket)+2) 576 | BCount-- 577 | else if (A_LoopField=Bracket) 578 | BCount++ 579 | If (BCount=0) 580 | Bracket= 581 | LF .= A_LoopField 582 | Continue 583 | } else if (!Quote&&!Bracket&&InStr("[{",A_LoopField)){ 584 | Bracket:=A_LoopField 585 | BCount=1 586 | LF.=A_LoopField 587 | Continue 588 | } 589 | If (A_Index=Count&&k!=""){ 590 | v:=LF A_LoopField 591 | v:=Trim(v) 592 | If (InStr("""'",SubStr(v,0))&&SubStr(v,1,1)=SubStr(v,0)) 593 | v:=SubStr(v,2,StrLen(v)-2) 594 | } else If (!Quote&&!Bracket&&k!=""&&A_LoopField=","&&SubStr(value,A_Index+1,1)=A_Space){ 595 | ContinueNext:=1 596 | LF:=Trim(LF) 597 | If VQ 598 | LF:=SubStr(LF,2,StrLen(LF)-2) 599 | v:=LF,LF:="" 600 | } else if (!Quote&&!Bracket&&k=""&&A_LoopField=":"){ 601 | LF:=Trim(LF) 602 | If (InStr("""'",SubStr(LF,0))&&SubStr(LF,1,1)=SubStr(LF,0)) 603 | LF:=SubStr(LF,2,StrLen(LF)-2) 604 | k:=LF,LF:="" 605 | continue 606 | } else { 607 | LF .= A_LoopField 608 | continue 609 | } 610 | If (obj=""){ 611 | If VQ= 612 | If (Asc(v)=91 && !Yaml_Seq("","",v)) 613 | ||(Asc(v)=123 && !Yaml_Map("","",v)) 614 | Return 0 615 | } else { 616 | If (VQ || !Yaml_SeqMap(cObj,k,v)) 617 | cObj[KQ?Yaml_UniChar(k):k]:=(VQ?Yaml_UniChar(v):Trim(v)) 618 | } 619 | k:="",v:="",VQ:="",KQ:="" 620 | } 621 | If (k){ 622 | If (obj=""){ 623 | If (Asc(LF)=91 && !Yaml_Seq("","",LF))||(Asc(LF)=123 && !Yaml_Map("","",LF)) 624 | Return 0 625 | } else { 626 | LF:=Trim(LF) 627 | If (VQ) 628 | LF:=SubStr(LF,2,StrLen(LF)-2),cObj[k]:=Yaml_UniChar(LF) 629 | else If (!Yaml_SeqMap(cObj,k,LF)) 630 | cObj[k]:=Trim(LF) 631 | } 632 | } 633 | Return (obj=""?(Quote Bracket=""):1) 634 | } 635 | Yaml_Incomplete(value){ 636 | return (Asc(Trim(value,"`n" A_Tab A_Space))=91 && !Yaml_Seq("","",Trim(value,"`n" A_Tab A_Space))) 637 | || (Asc(Trim(value,"`n" A_Tab A_Space))=123 && !Yaml_Map("","",Trim(value,"`n" A_Tab A_Space))) 638 | } 639 | Yaml_IsSeqMap(value){ 640 | return (Asc(Trim(value,"`n" A_Tab A_Space))=91 && Yaml_Seq("","",Trim(value,"`n" A_Tab A_Space))) 641 | || (Asc(Trim(value,"`n" A_Tab A_Space))=123 && Yaml_Map("","",Trim(value,"`n" A_Tab A_Space))) 642 | } -------------------------------------------------------------------------------- /Lib/class_EasyIni.ahk: -------------------------------------------------------------------------------- 1 | ; http://ahkscript.org/boards/viewtopic.php?f=6&t=5522&hilit=lib+ini 2 | ; Author : Verdlin 3 | class_EasyIni(sFile="", sLoadFromStr="") 4 | { 5 | return new EasyIni(sFile, sLoadFromStr) 6 | } 7 | 8 | class EasyIni 9 | { 10 | __New(sFile="", sLoadFromStr="") ; Loads ths file into memory. 11 | { 12 | this := this.CreateIniObj("EasyIni_ReservedFor_m_sFile", sFile 13 | , "EasyIni_ReservedFor_TopComments", Object()) ; Top comments can be stored in linear array because order will simply be numeric 14 | 15 | if (sFile == A_Blank && sLoadFromStr == A_Blank) 16 | return this 17 | 18 | ; Append ".ini" if it is not already there. 19 | if (SubStr(sFile, StrLen(sFile)-3, 4) != ".ini") 20 | this.EasyIni_ReservedFor_m_sFile := sFile := (sFile . ".ini") 21 | 22 | sIni := sLoadFromStr 23 | if (sIni == A_Blank) 24 | FileRead, sIni, %sFile% 25 | 26 | /* 27 | Current design (not fully implemented): 28 | --------------------------------------------------------------------------------------------------------------------------------------------------- 29 | Comments at the top of the section apply to the file as a whole. They are keyed off an internal section called "EasyIni_ReservedFor_TopComments." 30 | Comments above section headers apply to the the last key of the previous section. 31 | If a comment appears between two keys, then it will apply to the key above it -- this is consistent with the solution for comments above section headers. 32 | Newlines will be stored in similar fashion to comments. 33 | --------------------------------------------------------------------------------------------------------------------------------------------------- 34 | 35 | --------------------------------------------------------------------------------------------------------------------------------------------------- 36 | If full-support for comments needs to be added, then the design below should supersede the design above. 37 | By saying, "Full-support" I mean a way to directly access these comments based upon sections and keys. 38 | --------------------------------------------------------------------------------------------------------------------------------------------------- 39 | 40 | --------------------------------------------------------------------------------------------------------------------------------------------------- 41 | Comments at the top of the section apply to the file as a whole. They are keyed off an internal section called "EasyIni_ReservedFor_TopComments." 42 | Comments above section headers apply to the section header. If people dislike this, I may instead chose to make the comments apply to the last key of the previous section if there a newline in-between the comment in question and the next section. I may come up with some decent solution as I experiment 43 | If a comment appears between two keys, then it will apply to the key below it -- this is consistent with the solution for comments above section headers. 44 | Newlines will be stored in similar fashion to comments. 45 | --------------------------------------------------------------------------------------------------------------------------------------------------- 46 | */ 47 | 48 | Loop, Parse, sIni, `n, `r 49 | { 50 | sTrimmedLine := Trim(A_LoopField) 51 | 52 | ; Comments or newlines within the ini 53 | if (SubStr(sTrimmedLine, 1, 1) == ";" || sTrimmedLine == A_Blank) ; A_Blank would be a newline 54 | { 55 | ; Chr(14) is just the magical char to indicate that this line should only be a newline "`n" 56 | LoopField := A_LoopField == A_Blank ? Chr(14) : A_LoopField 57 | 58 | if (sCurSec == A_Blank) 59 | this.EasyIni_ReservedFor_TopComments.Insert(A_Index, LoopField) ; not using sTrimmedLine so as to keep comment formatting 60 | else 61 | { 62 | if (sPrevKeyForThisSec == A_Blank) ; This happens when there is a comment in the section before the first key, if any 63 | sPrevKeyForThisSec := "SectionComment" 64 | 65 | if (IsObject(this[sCurSec].EasyIni_ReservedFor_Comments)) 66 | { 67 | if (this[sCurSec].EasyIni_ReservedFor_Comments.HasKey(sPrevKeyForThisSec)) 68 | this[sCurSec].EasyIni_ReservedFor_Comments[sPrevKeyForThisSec] .= "`n" LoopField 69 | else this[sCurSec].EasyIni_ReservedFor_Comments.Insert(sPrevKeyForThisSec, LoopField) 70 | } 71 | else 72 | { 73 | if (IsObject(this[sCurSec])) 74 | this[sCurSec].EasyIni_ReservedFor_Comments := {(sPrevKeyForThisSec):LoopField} 75 | else this[sCurSec, "EasyIni_ReservedFor_Comments"] := {(sPrevKeyForThisSec):LoopField} 76 | } 77 | } 78 | continue 79 | } 80 | 81 | ; [Section] 82 | if (SubStr(sTrimmedLine, 1, 1) = "[" && InStr(sTrimmedLine, "]")) ; need to be sure that this isn't just a key starting with "[" 83 | { 84 | if (sCurSec != A_Blank && !this.HasKey(sCurSec)) 85 | this[sCurSec] := EasyIni_CreateBaseObj() 86 | sCurSec := SubStr(sTrimmedLine, 2, InStr(sTrimmedLine, "]", false, 0) - 2) ; 0 search right to left. We want to trim the *last* occurence of "]" 87 | sPrevKeyForThisSec := "" 88 | continue 89 | } 90 | 91 | ; key=val 92 | iPosOfEquals := InStr(sTrimmedLine, "=") 93 | if (iPosOfEquals) 94 | { 95 | sPrevKeyForThisSec := SubStr(sTrimmedLine, 1, iPosOfEquals - 1) ; so it's not the previous key yet...but it will be on next iteration :P 96 | val := SubStr(sTrimmedLine, iPosOfEquals + 1) 97 | StringReplace, val, val , `%A_ScriptDir`%, %A_ScriptDir%, All 98 | StringReplace, val, val , `%A_WorkingDir`%, %A_ScriptDir%, All 99 | this[sCurSec, sPrevKeyForThisSec] := val 100 | } 101 | else ; at this point, we know it isn't a comment, or newline, it isn't a section, and it isn't a conventional key-val pair. Treat this line as a key with no val 102 | { 103 | sPrevKeyForThisSec := sTrimmedLine 104 | this[sCurSec, sPrevKeyForThisSec] := "" 105 | } 106 | } 107 | ; if there is a section with no keys and it is at the bottom of the file, then we missed it 108 | if (sCurSec != A_Blank && !this.HasKey(sCurSec)) 109 | this[sCurSec] := EasyIni_CreateBaseObj() 110 | 111 | return this 112 | } 113 | 114 | CreateIniObj(parms*) 115 | { 116 | ; Define prototype object for ini arrays: 117 | static base := {__Set: "EasyIni_Set", _NewEnum: "EasyIni_NewEnum", Remove: "EasyIni_Remove", Insert: "EasyIni_Insert", InsertBefore: "EasyIni_InsertBefore", AddSection: "EasyIni.AddSection", RenameSection: "EasyIni.RenameSection", DeleteSection: "EasyIni.DeleteSection", GetSections: "EasyIni.GetSections", FindSecs: "EasyIni.FindSecs", AddKey: "EasyIni.AddKey", RenameKey: "EasyIni.RenameKey", DeleteKey: "EasyIni.DeleteKey", GetKeys: "EasyIni.GetKeys", FindKeys: "EasyIni.FindKeys", GetVals: "EasyIni.GetVals", FindVals: "EasyIni.FindVals", HasVal: "EasyIni.HasVal", Copy: "EasyIni.Copy", Merge: "EasyIni.Merge", GetFileName: "EasyIni.GetFileName", GetOnlyIniFileName:"EasyIni.GetOnlyIniFileName", IsEmpty:"EasyIni.IsEmpty", Reload: "EasyIni.Reload", GetIsSaved: "EasyIni.GetIsSaved", Save: "EasyIni.Save", ToVar: "EasyIni.ToVar"} 118 | ; Create and return new object: 119 | return Object("_keys", Object(), "base", base, parms*) 120 | } 121 | 122 | AddSection(sec, key="", val="", ByRef rsError="") 123 | { 124 | if (this.HasKey(sec)) 125 | { 126 | rsError := "Error! Cannot add new section [" sec "], because it already exists." 127 | return false 128 | } 129 | 130 | if (key == A_Blank) 131 | this[sec] := EasyIni_CreateBaseObj() 132 | else this[sec, key] := val 133 | 134 | return true 135 | } 136 | 137 | RenameSection(sOldSec, sNewSec, ByRef rsError="") 138 | { 139 | if (!this.HasKey(sOldSec)) 140 | { 141 | rsError := "Error! Could not rename section [" sOldSec "], because it does not exist." 142 | return false 143 | } 144 | 145 | aKeyValsCopy := this[sOldSec] 146 | this.DeleteSection(sOldSec) 147 | this[sNewSec] := aKeyValsCopy 148 | return true 149 | } 150 | 151 | DeleteSection(sec) 152 | { 153 | this.Remove(sec) 154 | return 155 | } 156 | 157 | GetSections(sDelim="`n", sSort="") 158 | { 159 | for sec in this 160 | secs .= (A_Index == 1 ? sec : sDelim sec) 161 | 162 | if (sSort) 163 | Sort, secs, D%sDelim% %sSort% 164 | 165 | return secs 166 | } 167 | 168 | FindSecs(sExp, iMaxSecs="") 169 | { 170 | aSecs := [] 171 | for sec in this 172 | { 173 | if (RegExMatch(sec, sExp)) 174 | { 175 | aSecs.Insert(sec) 176 | if (iMaxSecs&& aSecs.MaxIndex() == iMaxSecs) 177 | return aSecs 178 | } 179 | } 180 | return aSecs 181 | } 182 | 183 | AddKey(sec, key, val="", ByRef rsError="") 184 | { 185 | if (this.HasKey(sec)) 186 | { 187 | if (this[sec].HasKey(key)) 188 | { 189 | rsError := "Error! Could not add key, " key " because there is a key in the same section:`nSection: " sec "`nKey: " key 190 | return false 191 | } 192 | } 193 | else 194 | { 195 | rsError := "Error! Could not add key, " key " because Section, " sec " does not exist." 196 | return false 197 | } 198 | this[sec, key] := val 199 | return true 200 | } 201 | 202 | RenameKey(sec, OldKey, NewKey, ByRef rsError="") 203 | { 204 | if (!this[sec].HasKey(OldKey)) 205 | { 206 | rsError := "Error! The specified key " OldKey " could not be modified because it does not exist." 207 | return false 208 | } 209 | 210 | ValCopy := this[sec][OldKey] 211 | this.DeleteKey(sec, OldKey) 212 | this.AddKey(sec, NewKey) 213 | this[sec][NewKey] := ValCopy 214 | return true 215 | } 216 | 217 | DeleteKey(sec, key) 218 | { 219 | this[sec].Remove(key) 220 | return 221 | } 222 | 223 | GetKeys(sec, sDelim="`n", sSort="") 224 | { 225 | for key in this[sec] 226 | keys .= A_Index == 1 ? key : sDelim key 227 | 228 | if (sSort) 229 | Sort, keys, D%sDelim% %sSort% 230 | 231 | return keys 232 | } 233 | 234 | FindKeys(sec, sExp, iMaxKeys="") 235 | { 236 | aKeys := [] 237 | for key in this[sec] 238 | { 239 | if (RegExMatch(key, sExp)) 240 | { 241 | aKeys.Insert(key) 242 | if (iMaxKeys && aKeys.MaxIndex() == iMaxKeys) 243 | return aKeys 244 | } 245 | } 246 | return aKeys 247 | } 248 | 249 | ; Non-regex, exact match on key 250 | ; returns key(s) and their assocationed section(s) 251 | FindExactKeys(key, iMaxKeys="") 252 | { 253 | aKeys := {} 254 | for sec, aData in this 255 | { 256 | if (aData.HasKey(key)) 257 | { 258 | aKeys.Insert(sec, key) 259 | if (iMaxKeys && aKeys.MaxIndex() == iMaxKeys) 260 | return aKeys 261 | } 262 | } 263 | return aKeys 264 | } 265 | 266 | GetVals(sec, sDelim="`n", sSort="") 267 | { 268 | for key, val in this[sec] 269 | vals .= A_Index == 1 ? val : sDelim val 270 | 271 | if (sSort) 272 | Sort, vals, D%sDelim% %sSort% 273 | 274 | return vals 275 | } 276 | 277 | GetValue(sec, key) 278 | { 279 | return this[sec, key] 280 | } 281 | 282 | FindVals(sec, sExp, iMaxVals="") 283 | { 284 | aVals := [] 285 | for key, val in this[sec] 286 | { 287 | if (RegExMatch(val, sExp)) 288 | { 289 | aVals.Insert(val) 290 | if (iMaxVals && aVals.MaxIndex() == iMaxVals) 291 | break 292 | } 293 | } 294 | return aVals 295 | } 296 | 297 | HasVal(sec, FindVal) 298 | { 299 | for k, val in this[sec] 300 | if (FindVal = val) 301 | return true 302 | return false 303 | } 304 | 305 | ; SourceIni: May be EasyIni object or simply a path to an ini file. 306 | ; bCopyFileName = true: Allow copying of data without copying the file name. 307 | Copy(SourceIni, bCopyFileName = true) 308 | { 309 | ; Get ini as string. 310 | if (IsObject(SourceIni)) 311 | sIniString := SourceIni.ToVar() 312 | else FileRead, sIniString, %SourceIni% 313 | 314 | ; Effectively make this function static by allowing calls via EasyIni.Copy. 315 | if (IsObject(this)) 316 | { 317 | if (bCopyFileName) 318 | sOldFileName := this.GetFileName() 319 | this := A_Blank ; avoid any copy constructor issues. 320 | 321 | ; ObjClone doesn't work consistently. It's likely a problem with the meta-function overrides, 322 | ; but this is a nice, quick hack. 323 | this := class_EasyIni(SourceIni.GetFileName(), sIniString) 324 | 325 | ; Restore file name. 326 | this.EasyIni_ReservedFor_m_sFile := sOldFileName 327 | } 328 | else 329 | return class_EasyIni(bCopyFileName ? SourceIni.GetFileName() : "", sIniString) 330 | 331 | return this 332 | } 333 | 334 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 335 | /* 336 | Author: Verdlin 337 | STILL UNDER CONSTRUCTION. Need to handle comments, and then this will be complete. 338 | Function: Merge 339 | Purpose: Merge two EasyIni objects. 340 | Parameters 341 | vOtherIni: Other EasyIni object to merge with this. 342 | bRemoveNonMatching: If true, removes sections and keys that do not exist in both inis. 343 | bOverwriteMatching: If true, any key that exists in both objects will use the val from vOtherIni. 344 | vExceptionsIni: class_Easy ini object full of exceptions keys for secs. Any matching key will remain unchanged. 345 | */ 346 | Merge(vOtherIni, bRemoveNonMatching = false, bOverwriteMatching = false, vExceptionsIni = "") 347 | { 348 | ; TODO: Perhaps just save one ini, read it back in, and then perform merging? I think this would help with formatting. 349 | ; [Sections] 350 | for sec, aKeysAndVals in vOtherIni 351 | { 352 | if (!this.HasKey(sec)) 353 | if (bRemoveNonMatching) 354 | this.DeleteSection(sec) 355 | else this.AddSection(sec) 356 | 357 | ; key=val 358 | for key, val in aKeysAndVals 359 | { 360 | bMakeException := vExceptionsIni[sec].HasKey(key) 361 | 362 | if (this[sec].HasKey(key)) 363 | { 364 | if (bOverwriteMatching && !bMakeException) 365 | this[sec, key] := val 366 | } 367 | else 368 | { 369 | if (bRemoveNonMatching && !bMakeException) 370 | this.DeleteKey(sec, key) 371 | else if (!bRemoveNonMatching) 372 | this.AddKey(sec, key, val) 373 | } 374 | } 375 | } 376 | return 377 | } 378 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 379 | 380 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 381 | /* 382 | Author: Verdlin 383 | Function: GetFileName 384 | Purpose: Wrapper to return the extremely long named member var, EasyIni_ReservedFor_m_sFile 385 | Parameters 386 | None 387 | */ 388 | GetFileName() 389 | { 390 | return this.EasyIni_ReservedFor_m_sFile 391 | } 392 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 393 | 394 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 395 | /* 396 | Author: Verdlin 397 | Function: GetFileName 398 | Purpose: Wrapper to return just the .ini name without the path. 399 | Parameters 400 | None 401 | */ 402 | GetOnlyIniFileName() 403 | { 404 | return SubStr(this.EasyIni_ReservedFor_m_sFile, InStr(this.EasyIni_ReservedFor_m_sFile,"\", false, -1)+1) 405 | } 406 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 407 | 408 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 409 | /* 410 | Author: Verdlin 411 | Function: IsEmpty 412 | Purpose: To indicate whether or not this ini has data 413 | Parameters 414 | None 415 | */ 416 | IsEmpty() 417 | { 418 | return (this.GetSections() == A_Blank ; No sections. 419 | && !this.EasyIni_ReservedFor_TopComments.HasKey(1)) ; and no comments. 420 | } 421 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 422 | 423 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 424 | /* 425 | Author: Verdlin 426 | Function: Reload 427 | Purpose: Reloads object from ini file. This is necessary when other routines may be modifying the same ini file. 428 | Parameters 429 | None 430 | */ 431 | Reload() 432 | { 433 | if (FileExist(this.GetFileName())) 434 | this := class_EasyIni(this.GetFileName()) ; else nothing to reload. 435 | return this 436 | } 437 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 438 | 439 | ; TODO: Add option to store load and save times in comment at bottom of ini? 440 | Save(sSaveAs="", bWarnIfExist=false) 441 | { 442 | if (sSaveAs == A_Blank) 443 | sFile := this.GetFileName() 444 | else 445 | { 446 | sFile := sSaveAs 447 | 448 | ; Append ".ini" if it is not already there. 449 | if (SubStr(sFile, StrLen(sFile)-3, 4) != ".ini") 450 | sFile .= ".ini" 451 | 452 | if (bWarnIfExist && FileExist(sFile)) 453 | { 454 | MsgBox, 4,, The file "%sFile%" already exists.`n`nAre you sure that you want to overwrite it? 455 | IfMsgBox, No 456 | return false 457 | } 458 | } 459 | 460 | ; Formatting is preserved in ini object. 461 | FileDelete, %sFile% 462 | 463 | bIsFirstLine := true 464 | for k, v in this.EasyIni_ReservedFor_TopComments 465 | { 466 | FileAppend, % (A_Index == 1 ? "" : "`n") (v == Chr(14) ? "" : v), %sFile% 467 | bIsFirstLine := false 468 | } 469 | 470 | for section, aKeysAndVals in this 471 | { 472 | FileAppend, % (bIsFirstLine ? "[" : "`n[") section "]", %sFile% 473 | bIsFirstLine := false 474 | 475 | bEmptySection := true 476 | for key, val in aKeysAndVals 477 | { 478 | bEmptySection := false 479 | FileAppend, `n%key%=%val%, %sFile% 480 | 481 | ; Add the comment(s) for this key 482 | sComments := this[section].EasyIni_ReservedFor_Comments[key] 483 | Loop, Parse, sComments, `n 484 | FileAppend, % "`n" (A_LoopField == Chr(14) ? "" : A_LoopField), %sFile% 485 | } 486 | if (bEmptySection) 487 | { 488 | ; An empy section may contain comments... 489 | sComments := this[section].EasyIni_ReservedFor_Comments["SectionComment"] 490 | Loop, Parse, sComments, `n 491 | FileAppend, % "`n" (A_LoopField == Chr(14) ? "" : A_LoopField), %sFile% 492 | } 493 | } 494 | return true 495 | } 496 | 497 | ToVar() 498 | { 499 | sTmpFile := "$$$EasyIni_Temp.ini" 500 | this.Save(sTmpFile, !A_IsCompiled) 501 | FileRead, sIniAsVar, %sTmpFile% 502 | FileDelete, %sTmpFile% 503 | return sIniAsVar 504 | } 505 | } 506 | 507 | ; For all of the EasyIni_* functions below, much credit is due to Lexikos and Rbrtryn for their work with ordered arrays 508 | ; See http://www.autohotkey.com/board/topic/61792-ahk-l-for-loop-in-order-of-key-value-pair-creation/?p=389662 for Lexikos's initial work with ordered arrays 509 | ; See http://www.autohotkey.com/board/topic/94043-ordered-array/#entry592333 for Rbrtryn's OrderedArray lib 510 | EasyIni_CreateBaseObj(parms*) 511 | { 512 | ; Define prototype object for ordered arrays: 513 | static base := {__Set: "EasyIni_Set", _NewEnum: "EasyIni_NewEnum", Remove: "EasyIni_Remove", Insert: "EasyIni_Insert", InsertBefore: "EasyIni_InsertBefore"} 514 | ; Create and return new base object: 515 | return Object("_keys", Object(), "base", base, parms*) 516 | } 517 | 518 | EasyIni_Set(obj, parms*) 519 | { 520 | ; If this function is called, the key must not already exist. 521 | ; Sub-class array if necessary then add this new key to the key list, if it doesn't begin with "EasyIni_ReservedFor_" 522 | if parms.maxindex() > 2 523 | ObjInsert(obj, parms[1], EasyIni_CreateBaseObj()) 524 | 525 | ; Skip over member variables 526 | if (SubStr(parms[1], 1, 20) <> "EasyIni_ReservedFor_") 527 | ObjInsert(obj._keys, parms[1]) 528 | ; Since we don't return a value, the default behaviour takes effect. 529 | ; That is, a new key-value pair is created and stored in the object. 530 | } 531 | 532 | EasyIni_NewEnum(obj) 533 | { 534 | ; Define prototype object for custom enumerator: 535 | static base := Object("Next", "EasyIni_EnumNext") 536 | ; Return an enumerator wrapping our _keys array's enumerator: 537 | return Object("obj", obj, "enum", obj._keys._NewEnum(), "base", base) 538 | } 539 | 540 | EasyIni_EnumNext(e, ByRef k, ByRef v="") 541 | { 542 | ; If Enum.Next() returns a "true" value, it has stored a key and 543 | ; value in the provided variables. In this case, "i" receives the 544 | ; current index in the _keys array and "k" receives the value at 545 | ; that index, which is a key in the original object: 546 | if r := e.enum.Next(i,k) 547 | ; We want it to appear as though the user is simply enumerating 548 | ; the key-value pairs of the original object, so store the value 549 | ; associated with this key in the second output variable: 550 | v := e.obj[k] 551 | return r 552 | } 553 | 554 | EasyIni_Remove(obj, parms*) 555 | { 556 | r := ObjRemove(obj, parms*) ; Remove keys from main object 557 | Removed := [] 558 | for k, v in obj._keys ; Get each index key pair 559 | if not ObjHasKey(obj, v) ; if key is not in main object 560 | Removed.Insert(k) ; Store that keys index to be removed later 561 | for k, v in Removed ; For each key to be removed 562 | ObjRemove(obj._keys, v, "") ; remove that key from key list 563 | 564 | return r 565 | } 566 | 567 | EasyIni_Insert(obj, parms*) 568 | { 569 | r := ObjInsert(obj, parms*) ; Insert keys into main object 570 | enum := ObjNewEnum(obj) ; Can't use for-loop because it would invoke EasyIni_NewEnum 571 | while enum[k] { ; For each key in main object 572 | for i, kv in obj._keys ; Search for key in obj._keys 573 | if (k = "_keys" || k = kv || SubStr(k, 1, 20) = "EasyIni_ReservedFor_" || SubStr(kv, 1, 20) = "EasyIni_ReservedFor_") ; If found... 574 | continue 2 ; Get next key in main object 575 | ObjInsert(obj._keys, k) ; Else insert key into obj._keys 576 | } 577 | 578 | return r 579 | } 580 | 581 | EasyIni_InsertBefore(obj, key, parms*) 582 | { 583 | OldKeys := obj._keys ; Save key list 584 | obj._keys := [] ; Clear key list 585 | for idx, k in OldKeys { ; Put the keys before key 586 | if (k = key) ; back into key list 587 | break 588 | obj._keys.Insert(k) 589 | } 590 | 591 | r := ObjInsert(obj, parms*) ; Insert keys into main object 592 | enum := ObjNewEnum(obj) ; Can't use for-loop because it would invoke EasyIni_NewEnum 593 | while enum[k] { ; For each key in main object 594 | for i, kv in OldKeys ; Search for key in OldKeys 595 | if (k = "_keys" || k = kv) ; If found... 596 | continue 2 ; Get next key in main object 597 | ObjInsert(obj._keys, k) ; Else insert key into obj._keys 598 | } 599 | 600 | for i, k in OldKeys { ; Put the keys after key 601 | if (i < idx) ; back into key list 602 | continue 603 | obj._keys.Insert(k) 604 | } 605 | 606 | return r 607 | } 608 | -------------------------------------------------------------------------------- /Lib/class_vim.ahk: -------------------------------------------------------------------------------- 1 | ; 初始化class_Vim 2 | vim_Init: 3 | #UseHook 4 | SetKeyDelay,-1 5 | return 6 | ; 用于热键映射 7 | vim_Key: 8 | vim.Key() 9 | return 10 | ; 用于热键超时 11 | vim_TimeOut: 12 | vim.IsTimeOut() 13 | return 14 | ; 用于Count计数 15 | Internal: 16 | __v.SetPlugin("Internal","Array","0.1","内置插件") 17 | __v.SetAction("<1>","Number 1") 18 | __v.SetAction("<2>","Number 2") 19 | __v.SetAction("<3>","Number 3") 20 | __v.SetAction("<4>","Number 4") 21 | __v.SetAction("<5>","Number 5") 22 | __v.SetAction("<6>","Number 6") 23 | __v.SetAction("<7>","Number 7") 24 | __v.SetAction("<8>","Number 8") 25 | __v.SetAction("<9>","Number 9") 26 | __v.SetAction("<0>","Number 0") 27 | __v.SetAction("<>","Null") 28 | __v := "" 29 | return 30 | <1>: 31 | <2>: 32 | <3>: 33 | <4>: 34 | <5>: 35 | <6>: 36 | <7>: 37 | <8>: 38 | <9>: 39 | <0>: 40 | <>: 41 | return 42 | 43 | Class_vim() 44 | { 45 | global __v 46 | GoSub,Vim_Init 47 | __v := v :=new __vim 48 | __v.LoadPlugin("Internal") 49 | return v 50 | } 51 | ShowInfo() 52 | { 53 | Global vim 54 | Tooltip % vim.GetMore() 55 | } 56 | HideInfo() 57 | { 58 | Tooltip 59 | } 60 | 61 | ; 定义数据结构 62 | ; Class __vim {{{1 63 | Class __vim 64 | { 65 | __new() 66 | { 67 | this.pluginList := [] 68 | this.winList := [] 69 | this.winInfo := [] 70 | this.ActionList := [] 71 | this.ActionFromPlugin := [] 72 | this.ExcludeWinList :=[] 73 | this.winGlobal := new __win 74 | this.ErrorCode := 0 75 | tihs.ActionFromPluginName := "" 76 | this.LastFoundWin := "" 77 | } 78 | ; LoadPlugin(PluginName) {{{2 79 | ; 用于注册插件 80 | LoadPlugin(PluginName) 81 | { 82 | If this.pluginList[PluginName] 83 | return this.pluginList[PluginName] 84 | p := new __Plugin(PluginName) 85 | this.pluginList[PluginName] := p 86 | back := this.ActionFromPluginName 87 | this.ActionFromPluginName := PluginName 88 | p.CheckSub() 89 | If p.Error 90 | { 91 | msgbox load plugin error 92 | this.ActionFromPluginName := back 93 | } 94 | } 95 | ; SetPlugin(PluginName,Author="",Ver="",Comment="") {{{2 96 | ; 设置Plugin信息 97 | SetPlugin(PluginName,Author="",Ver="",Comment="") 98 | { 99 | p := this.pluginList[PluginName] 100 | p.Author := Author 101 | p.Ver := Ver 102 | p.Comment := Comment 103 | } 104 | ; GetPlugin(PluginName) {{{2 105 | ; 获取Plugin信息 106 | GetPlugin(PluginName) 107 | { 108 | return this.pluginList[PluginName] 109 | } 110 | ; Comment(action,desc,complex=1) {{{2 111 | ; 兼容老版本的vimcore.ahk 112 | Comment(action,desc="",complex=1) 113 | { 114 | act := this.SetAction(Action,Desc) 115 | If not complex ; 不允许多次运行 116 | act.SetMaxTimes(1) 117 | return act 118 | } 119 | ; SetAction(Name,Comment) {{{2 120 | ; 用于为Action(动作)进行注释 121 | SetAction(Name,Comment="") 122 | { 123 | If this.ActionList[Name] 124 | ra := This.ActionList[Name] 125 | Else 126 | ra := This.ActionList[Name] := new __Action(Name,Comment) 127 | This.ActionFromPlugin[Name] := this.ActionFromPluginName 128 | return ra 129 | } 130 | ; GetAction(Name) {{{2 131 | ; 获取Action的信息 132 | GetAction(Name) 133 | { 134 | return this.ActionList[Name] 135 | } 136 | ; SetWin(winName,class,filepath,title) {{{2 137 | ; 添加win成员 138 | SetWin(winName,class,filepath="",title="") 139 | { 140 | If this.winList[winName] 141 | rw := this.winList[winName] 142 | Else 143 | rw := this.winList[winName] := new __win(class,filepath,title) 144 | this.winInfo["class`t"class] := winName 145 | this.winInfo["filepath`t"filepath] := winName 146 | this.winInfo["title`t"title] := winName 147 | return rw 148 | } 149 | ; GetWin(winName) {{{2 150 | GetWin(winName="") 151 | { 152 | If strlen(winName) 153 | return this.winList[winName] 154 | Else 155 | return this.winGlobal 156 | } 157 | ; CheckWin() {{{2 158 | CheckWin() 159 | { 160 | /* 161 | WinGetTitle,t,A 162 | If Strlen(winName:=this.winInfo["title`t"t]) 163 | return winName 164 | */ 165 | WinGet,f,ProcessName,A 166 | If Strlen(winName:=this.winInfo["filepath`t"f]) 167 | return winName 168 | WinGetClass,c,A 169 | If Strlen(winName:=this.winInfo["class`t"c]) 170 | return winName 171 | } 172 | ; mode(mode,win="") {{{2 173 | ; 兼容老版本的vimcore.ahk 174 | mode(mode,win="") 175 | { 176 | If not IsObject(this.GetWin(win)) 177 | this.SetWin(win,win) 178 | return this.SetMode(mode,win) 179 | } 180 | ; SetMode(modeName,winName) {{{2 181 | SetMode(modeName,winName="") 182 | { 183 | winObj := This.GetWin(winName) 184 | return winObj.ChangeMode(modeName) 185 | } 186 | ; SetModeFunction(func,modeName,winName="") {{{2 187 | SetModeFunction(func,modeName,winName="") 188 | { 189 | winObj := This.GetWin(winName) 190 | modeObj := winObj.modeList[modeName] 191 | modeObj.modeFunction := func 192 | } 193 | ; GetMode(winName) {{{2 194 | ; 获取指定win中当前的模式 195 | GetMode(winName="") 196 | { 197 | winObj := This.GetWin(winName) 198 | return winObj.modeList[winobj.ExistMode()] 199 | } 200 | ; BeforeActionDo(Function,winName="") {{{2 201 | BeforeActionDo(Function,winName="") 202 | { 203 | winObj := this.GetWin(winName) 204 | winObj.BeforeActionDoFunc:= Function 205 | } 206 | ; AfterActionDo(Function,winName="") {{{2 207 | AfterActionDo(Function,winName="") 208 | { 209 | winObj := this.GetWin(winName) 210 | winObj.AfterActionDoFunc:= Function 211 | } 212 | 213 | ; 214 | ; SetMaxCount(Int,winName) {{{2 215 | SetMaxCount(Int,winName="") 216 | { 217 | winObj := This.GetWin(winName) 218 | winObj.MaxCount := int 219 | } 220 | ; GetMaxCount(winName) {{{2 221 | GetMaxCount(winName="") 222 | { 223 | winObj := This.GetWin(winName) 224 | return winObj.MaxCount 225 | } 226 | ; SetCount(int,winName) {{{2 227 | SetCount(int,winName="") 228 | { 229 | winObj := This.GetWin(winName) 230 | winObj.Count := int 231 | } 232 | ; GetCount(winName) {{{2 233 | GetCount(winName="") 234 | { 235 | winObj := This.GetWin(winName) 236 | return winObj.Count 237 | } 238 | ; SetTimeOut(Int,winName) {{{2 239 | SetTimeOut(Int,winName="") 240 | { 241 | winObj := This.GetWin(winName) 242 | winObj.TimeOut := int 243 | } 244 | ; GetTimeOut(winName) {{{2 245 | GetTimeOut(winName="") 246 | { 247 | winObj := This.GetWin(winName) 248 | return winObj.TimeOut 249 | } 250 | 251 | ; Map(keyName,Action,winName) {{{2 252 | ; 例 Map("jjj",,"TC") 253 | ; Map("jk",,"TC") 254 | Map(keyName,Action,winName="") 255 | { 256 | If not this.GetAction(Action) 257 | { 258 | If Islabel(action) 259 | this.SetAction(Action,Action) 260 | Else 261 | { 262 | msgbox % "map " keyname " to " action " error" 263 | return 264 | } 265 | } 266 | winObj := This.GetWin(winName) 267 | modeObj := this.GetMode(winName) 268 | Class:=winObj.class 269 | filepath := winObj.filepath 270 | If winName 271 | { 272 | If strlen(filepath) 273 | Hotkey,IfWinActive,ahk_exe %filepath% 274 | Else 275 | Hotkey,IfWinActive,ahk_class %class% 276 | } 277 | Else 278 | Hotkey,IfWinActive 279 | keyName := RegExReplace(keyName,"i)","",nowait) 280 | keyName := RegExReplace(keyName,"i)","",super) 281 | newkeyName := keyName 282 | index := 0 283 | Loop 284 | { 285 | If not strlen(newkeyName) 286 | break 287 | Else 288 | { 289 | saveMoreKey .= thisKey 290 | modeobj.SetMoreKey(saveMoreKey) 291 | } 292 | If RegExMatch(newkeyName,"P)^<.+?>",m) 293 | { 294 | thisKey := SubStr(newkeyName,1,m) 295 | newkeyName := SubStr(newkeyName,m+1) 296 | } 297 | Else 298 | { 299 | thisKey := SubStr(newkeyName,1,1) 300 | newKeyName := SubStr(newkeyName,2) 301 | } 302 | If RegExMatch(thisKey,"^([A-Z])$",m) 303 | thisKey := "" 304 | SaveKeyName .= thisKey 305 | key := this.Convert2AHK(thisKey) 306 | this.Debug.Add("Map: " thiskey " to: " Action) 307 | Hotkey,%Key%,Vim_Key,On,UseErrorLevel 308 | If ErrorLevel 309 | Msgbox % KeyName "`n" key "`n映射错误" 310 | Else 311 | { 312 | winObj.SuperKeyList[key] := super 313 | winObj.KeyList[key] := True 314 | Index++ 315 | } 316 | } 317 | modeObj.SetKeyMap(SavekeyName,Action) 318 | modeObj.SetNoWait(SavekeyName,nowait) 319 | } 320 | 321 | ; ExcludeWin(winName="",Bold=True) {{{2 322 | ExcludeWin(winName="",Bold=True) 323 | { 324 | this.ExcludeWinList[winName] := Bold 325 | } 326 | ; Toggle(winName) {{{2 327 | Toggle(winName) 328 | { 329 | winObj := this.GetWin(winName) 330 | winObj.Status := !winObj.Status 331 | this.Control(winObj.Status,winName) 332 | } 333 | ; Control(bold,winName) {{{2 334 | Control(bold,winName="",all=false) 335 | { 336 | winObj := this.GetWin(winName) 337 | class := winObj.Class 338 | filepath := winObj.filepath 339 | If Strlen(filepath) 340 | Hotkey,IfWinActive,ahk_exe %filepath% 341 | Else If Strlen(class) 342 | Hotkey,IfWinActive,ahk_class %class% 343 | Else 344 | Hotkey,IfWinActive 345 | this.Debug.Add("===== Control End =====") 346 | for i , k in winObj.KeyList 347 | { 348 | If winObj.SuperKeyList[i] And ( not all ) 349 | Continue 350 | this.Debug.Add("class: " class "`tkey: " i "`tcontrol: " bold ) 351 | If bold 352 | Hotkey,%i%,Vim_Key,On 353 | Else 354 | Hotkey,%i%,Vim_Key,off 355 | winObj.KeyList[i] := bold 356 | } 357 | this.Debug.Add("===== Control Start =====") 358 | } 359 | ; Copy(winName1,winName2) {{{2 360 | ; 复制winName1到winName2,winName2按class/filepath/title定义 361 | Copy(winName1,winName2,class,filepath="",title="") 362 | { 363 | this.debug.Add("Copy>> "winName1 "`t" winName2 "`t" class) 364 | w1 := This.GetWin(winName1) 365 | w2 := this.SetWin(winName2,class,filepath,title) 366 | w2.class := class 367 | w2.filepath := filepath 368 | w2.title := title 369 | w2.KeyList := w1.KeyList 370 | w2.SuperKeyList := w1.SuperKeyList 371 | w2.modeList := w1.modeList 372 | w2.mode := w1.mode 373 | w2.LastKey := w1.LastKey 374 | w2.KeyTemp := w1.KeyTemp 375 | w2.MaxCount := w1.MaxCount 376 | w2.Count := w1.Count 377 | w2.TimeOut := w1.TimeOut 378 | w2.Info := w1.Info 379 | w2.BeforeActionDoFunc := w1.BeforeActionDoFunc 380 | w2.AfterActionDoFunc := w1.AfterActionDoFunc 381 | w2.ShowInfoFunc := w1.ShowInfoFunc 382 | w2.HideInfoFunc := w1.HideInfoFunc 383 | this.Control(Bold:=True,winName2,all:=true) 384 | return w2 385 | } 386 | 387 | ; CopyMode(win,mode,to) {{{2 388 | ; 在当前的Win中复制一个模式 389 | CopyMode(winName,fromMode,toMode) 390 | { 391 | winObj := This.GetWin(winName) 392 | winObj.mode := modeName 393 | winObj.KeyTemp := "" 394 | winObj.Count := 0 395 | from:=winObj.modeList[fromMode] 396 | from.name := toMode 397 | winObj.modeList[toMode] := from 398 | return from 399 | } 400 | 401 | ; Delete(winName) {{{2 402 | Delete(winName="") { 403 | this.Control(False,winName,all:=True) 404 | this.winList[winName] := "" 405 | } 406 | 407 | 408 | ; GetMore() {{{2 409 | GetMore() 410 | { 411 | winObj := this.GetWin(this.LastFoundWin) 412 | modeObj := this.GetMode(this.LastFoundWin) 413 | If Strlen(winObj.KeyTemp) 414 | { 415 | r := winObj.KeyTemp "`n" 416 | m := "i)^" this.ToMatch(winObj.KeyTemp) ".+" 417 | for i ,k in modeObj.keymapList 418 | { 419 | If RegExMatch(i,m) 420 | r .= i "`t" modeObj.GetKeyMap(i) "`n" 421 | } 422 | return r 423 | } 424 | Else 425 | If winobj.count 426 | return winobj.count 427 | } 428 | ; Clear() {{{2 429 | Clear(winName="") { 430 | winObj := This.GetWin(winName) 431 | winObj.KeyTemp := "" 432 | winObj.Count := 0 433 | } 434 | 435 | ; Key() {{{2 436 | Key() 437 | { 438 | ; 获取winName 439 | winName := this.CheckWin() 440 | ; 获取当前的热键 441 | k := this.CheckCapsLock(this.Convert2VIM(A_ThisHotkey)) 442 | ; 如果winName在排除窗口中,直接发送热键 443 | If this.ExcludeWinList[winName] { 444 | Send,% this.Convert2AHK(k,ToSend:=True) 445 | return 446 | } 447 | ; 如果当前热键在当前winName无效,判断全局热键中是否有效? 448 | winObj := this.GetWin(winName) 449 | If Not winObj.KeyList[A_thisHotkey] { 450 | winObj := this.GetWin() 451 | If Not winObj.KeyList[A_thisHotkey] { 452 | ; 无效热键,按普通键输出 453 | Send,% this.Convert2AHK(k,ToSend:=True) 454 | return 455 | } 456 | Else 457 | winName := "" 458 | } 459 | this.LastFoundWin := winName 460 | ; 执行在判断热键前的函数,如果函数返回True,按普通键输出 461 | If IsFunc(f:=winObj.BeforeActionDoFunc){ 462 | If %f%(){ 463 | Send,% this.Convert2AHK(k,ToSend:=True) 464 | return 465 | } 466 | } 467 | ; 获取当前模式对应的对象 468 | modeObj := this.GetMode(winName) 469 | ; 把当前热键添加到热键缓存中,并设置最后热键为k 470 | winObj.KeyTemp .= winObj.LastKey := k 471 | this.Debug.Add(" win: " winname "`tHotkey: " k) 472 | /* 473 | If winObj.Count 474 | this.Debug.Add(" [" winName "`t热键:" winObj.Count winObj.KeyTemp ) 475 | Else 476 | this.Debug.Add(" [" winName "]`t热键:" winObj.KeyTemp ) 477 | */ 478 | ; 热键缓存是否有对应的Action? 479 | ; 判断是否有更多热键,如果当前具有设置,则无视更多热键 480 | If modeObj.GetMoreKey(winObj.KeyTemp) And (Not modeObj.GetNoWait(winObj.KeyTemp)) { 481 | ; 启用TimeOut 482 | If tick := winObj.TimeOut 483 | Settimer,Vim_TimeOut,%tick% 484 | winObj.ShowMore() 485 | ; 执行在判断热键后的函数,如果函数返回True,按普通键输出 486 | If IsFunc(f:=winObj.AfterActionDoFunc){ 487 | If %f%() 488 | Send,% this.Convert2AHK(k,ToSend:=True) 489 | } 490 | return 491 | } 492 | ; 如果没有更多,热键缓存是否有对应的Action? 493 | If strlen(actionName := modeObj.GetKeymap(winObj.KeyTemp)) { 494 | actObj := this.GetAction(actionName) 495 | If ( actObj.Type = 0 ) And RegExMatch(actionName ,"^<(\d)>$",m) { 496 | ; 数字则进行累加 497 | winObj.Count := winObj.Count * 10 + m1 498 | If winObj.MaxCount And winObj.Count > winObj.MaxCount 499 | winObj.Count := winObj.MaxCount 500 | winObj.KeyTemp := "" 501 | winObj.ShowMore() 502 | If IsFunc(f:=winObj.AfterActionDoFunc) 503 | %f%() 504 | return 505 | } 506 | Else { 507 | ; 非数字则直接运行 508 | ;this.Debug.Add("act: " actionName "`tLK: " winObj.KeyTemp) 509 | actObj.Do(winObj.Count) 510 | winObj.Count := 0 511 | } 512 | } 513 | Else { 514 | ; 如果没有,按普通键输出 515 | If strlen(actionName := modeObj.GetKeymap(winObj.LastKey)) 516 | { 517 | actObj := this.GetAction(actionName) 518 | actObj.Do(winObj.Count) 519 | winObj.Count := 0 520 | } 521 | Else 522 | { 523 | Send,% this.Convert2AHK(k,ToSend:=True) 524 | winObj.Count := 0 525 | } 526 | } 527 | winObj.KeyTemp := "" 528 | winObj.HideMore() 529 | ; 执行在判断热键后的函数,如果函数返回True,按普通键输出 530 | If IsFunc(f:=winObj.AfterActionDoFunc){ 531 | If %f%() 532 | Send,% this.Convert2AHK(k,ToSend:=True) 533 | ; %f%() ;直接运行 534 | } 535 | return 536 | } 537 | ; IsTimeOut() {{{2 538 | IsTimeOut() 539 | { 540 | winObj := this.GetWin(this.LastFoundWin) 541 | modeObj := this.GetMode(this.LastFoundWin) 542 | act := this.GetAction(modeObj.GetKeyMap(winObj.KeyTemp)) 543 | If act 544 | { 545 | winObj.HideMore() 546 | act.Do(winObj.Count) 547 | winObj.Count := 0 548 | winObj.KeyTemp := "" 549 | ; 执行在判断热键后的函数,如果函数返回True,按普通键输出 550 | If IsFunc(f:=winObj.AfterActionDoFunc){ 551 | If %f%() 552 | Send,% this.Convert2AHK(k,ToSend:=True) 553 | } 554 | Settimer,Vim_TimeOut,Off 555 | } 556 | } 557 | ; Debug(Bold) {{{2 558 | Debug(Bold,history=false) 559 | { 560 | If Bold 561 | { 562 | this.Debug := new __vimDebug(history) 563 | this.Debug.var(this) 564 | } 565 | Else 566 | { 567 | GUI,vimDebug:Destroy 568 | this.Debug := "" 569 | } 570 | } 571 | ; Convert2VIM(key) {{{2 572 | ; 将AHK热键名转换为类VIM的热键名 573 | ; 例 Convert2VIM("f1") 574 | Convert2VIM(key) 575 | { 576 | If RegExMatch(key,"^[A-Z]$") 577 | return "" 578 | If RegExMatch(key,"i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$") 579 | return "<" key ">" 580 | If RegExMatch(key,"i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn))$") 581 | return "<" key ">" 582 | If RegExMatch(key,"i)^((BS)|(BackSpace))$") 583 | return "" 584 | If RegExMatch(key,"i)^((Esc)|(Escape))$") 585 | return "" 586 | If RegExMatch(key,"i)^((Ins)|(Insert))$") 587 | return "" 588 | If RegExMatch(key,"i)^((Del)|(Delete))$") 589 | return "" 590 | If RegExMatch(key,"i)^PrintScreen$") 591 | return "" 592 | If RegExMatch(key,"<") 593 | return "" 594 | If RegExMatch(key,">") 595 | return "" 596 | If RegExMatch(key,"i)^shift\s&\s(.*)",m) or RegExMatch(key,"^\+(.*)",m) 597 | return "" 598 | If RegExMatch(key,"i)^lshift\s&\s(.*)",m) 599 | return "" 600 | If RegExMatch(key,"i)^rshift\s&\s(.*)",m) 601 | return "" 602 | If RegExMatch(key,"i)^Ctrl\s&\s(.*)",m) or RegExMatch(key,"^\^(.*)",m) 603 | return "" 604 | If RegExMatch(key,"i)^lctrl\s&\s(.*)",m) 605 | return "" 606 | If RegExMatch(key,"i)^rctrl\s&\s(.*)",m) 607 | return "" 608 | If RegExMatch(key,"i)^alt\s&\s(.*)",m) or RegExMatch(key,"^\!(.*)",m) 609 | return "" 610 | If RegExMatch(key,"i)^lalt\s&\s(.*)",m) 611 | return "" 612 | If RegExMatch(key,"i)^ralt\s&\s(.*)",m) 613 | return "" 614 | If RegExMatch(key,"i)^lwin\s&\s(.*)",m) or RegExMatch(key,"^#(.*)",m) 615 | return "" 616 | If RegExMatch(key,"i)^alt$") 617 | return "" 618 | If RegExMatch(key,"i)^ctrl$") 619 | return "" 620 | If RegExMatch(key,"i)^shift$") 621 | return "" 622 | If RegExMatch(key,"i)^lwin$") 623 | return "" 624 | return key 625 | } 626 | Upper(k) 627 | { 628 | StringUpper,k,k 629 | return k 630 | } 631 | ; Convert2AHK(key,ToSend=False) {{{2 632 | ; 将类VIM的热键名转换为AHK热键名 633 | ; 例 Convert2AHK("") 634 | Convert2AHK(key,ToSend=False) 635 | { 636 | this.CheckCapsLock(key) 637 | If RegExMatch(key,"^<.*>$") 638 | { 639 | key := SubStr(key,2,strlen(key)-2) 640 | If RegExMatch(key,"i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$") 641 | return ToSend ? "{" key "}" : key 642 | If RegExMatch(key,"i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn)|(BS)|(ESC)|(Insert)|(Delete))$") 643 | return ToSend ? "{" key "}" : key 644 | If RegExMatch(key,"i)^PrtSc$") 645 | return ToSend ? "{PrintScreen}" : "PrintScreen" 646 | If RegExMatch(key,"i)^alt$") 647 | return ToSend ? "{!}" : "alt" 648 | If RegExMatch(key,"i)^ctrl$") 649 | return ToSend ? "{^}" : "ctrl" 650 | If RegExMatch(key,"i)^shift$") 651 | return ToSend ? "{+}" : "shift" 652 | If RegExMatch(key,"i)^win$") 653 | return ToSend ? "{#}" : "lwin" 654 | If RegExMatch(key,"") 655 | return "<" 656 | If RegExMatch(key,"") 657 | return ">" 658 | If RegExMatch(key,"i)^S\-(.*)",m) 659 | return ToSend ? "+" this.CheckToSend(m1) : "shift & " m1 660 | If RegExMatch(key,"i)^LS\-(.*)",m) 661 | return ToSend ? "+" this.CheckToSend(m1) : "lshift & " m1 662 | If RegExMatch(key,"i)^RS-(.*)",m) 663 | return ToSend ? "+" this.CheckToSend(m1) : "rshift & " m1 664 | If RegExMatch(key,"i)^C\-(.*)",m) 665 | return ToSend ? "^" this.CheckToSend(m1) : "ctrl & " m1 666 | If RegExMatch(key,"i)^LC\-(.*)",m) 667 | return ToSend ? "^" this.CheckToSend(m1) : "lctrl & " m1 668 | If RegExMatch(key,"i)^RC\-(.*)",m) 669 | return ToSend ? "^" this.CheckToSend(m1) : "rctrl & " m1 670 | If RegExMatch(key,"i)^A\-(.*)",m) 671 | return ToSend ? "!" this.CheckToSend(m1) : "alt & " m1 672 | If RegExMatch(key,"i)^LA\-(.*)",m) 673 | return ToSend ? "!" this.CheckToSend(m1) : "lalt & " m1 674 | If RegExMatch(key,"i)^RA\-(.*)",m) 675 | return ToSend ? "!" this.CheckToSend(m1) : "ralt & " m1 676 | If RegExMatch(key,"i)^w\-(.*)",m) 677 | return ToSend ? "#" this.CheckToSend(m1) : "lwin & " m1 678 | } 679 | Else 680 | return key 681 | } 682 | CheckToSend(key) 683 | { 684 | If RegExMatch(key,"i)^((F1)|(F2)|(F3)|(F4)|(F5)|(F6)|(F7)|(F8)|(F9)|(F10)|(F11)|(F12))$") 685 | return "{" key "}" 686 | If RegExMatch(key,"i)^((AppsKey)|(Tab)|(Enter)|(Space)|(Home)|(End)|(CapsLock)|(ScroollLock)|(Up)|(Down)|(Left)|(Right)|(PgUp)|(PgDn)|(BS)|(ESC)|(Insert)|(Delete))$") 687 | return "{" key "}" 688 | If RegExMatch(key,"i)^PrtSc$") 689 | return "{PrintScreen}" 690 | If RegExMatch(key,"i)^alt$") 691 | return "{!}" 692 | If RegExMatch(key,"i)^ctrl$") 693 | return "{^}" 694 | If RegExMatch(key,"i)^shift$") 695 | return "{+}" 696 | If RegExMatch(key,"i)^win$") 697 | return "{#}" 698 | If RegExMatch(key,"") 699 | return "<" 700 | If RegExMatch(key,"") 701 | return ">" 702 | Return Key 703 | } 704 | ; CheckCapsLock(key) {{{2 705 | ; 检测CapsLock是否按下,返回对应的值 706 | ; key 的值为类VIM键,如 CheckCapsLock("") 707 | CheckCapsLock(key) 708 | { 709 | If GetKeyState("CapsLock","T") 710 | { 711 | If RegExMatch(key,"^[a-z]$") 712 | return "" 713 | If RegExMatch(key,"i)^",m) 714 | { 715 | StringLower, key, m1 716 | return key 717 | } 718 | } 719 | return key 720 | } 721 | ToMatch(v) 722 | { 723 | v := RegExReplace(v ,"\+|\?|\.|\*|\{|\}|\(|\)|\||\^|\$|\[|\]|\\","\$0") 724 | Return RegExReplace(v ,"\s","\s") 725 | } 726 | 727 | } 728 | ; Class __win {{{1 729 | Class __win 730 | { 731 | __new(class="",filepath="",title=""){ 732 | this.class := class 733 | this.filepath := filepath 734 | this.title := title 735 | this.KeyList := [] 736 | this.SuperKeyList := [] 737 | this.modeList := [] 738 | this.Status := True 739 | this.mode := "" 740 | this.LastKey := "" 741 | this.KeyTemp := "" 742 | this.MaxCount := 99 743 | this.Count := 0 744 | this.TimeOut := 0 745 | this.Info := True 746 | this.BeforeActionDoFunc := "" 747 | this.AfterActionDoFunc := "" 748 | this.ShowInfoFunc := "ShowInfo" 749 | this.HideInfoFunc := "HideInfo" 750 | } 751 | ; ChangeMode(modeName) {{{2 752 | ; 检查模式是否存在,如存在则返回模式对象,如果不存在则新建并返回模式对象 753 | ChangeMode(modeName) 754 | { 755 | this.mode := modeName 756 | this.KeyTemp := "" 757 | this.Count := 0 758 | If not this.modeList[modeName] 759 | this.modeList[modeName] := new __Mode(modeName) 760 | modeObj := this.modeList[modeName] 761 | If IsFunc(func := modeObj.modeFunction) 762 | %func%() 763 | return modeObj 764 | } 765 | ; ExistMode() {{{2 766 | ; 获取当前模式名 767 | ExistMode() 768 | { 769 | return this.mode 770 | } 771 | ; SetInfo() {{{2 772 | SetInfo(bold) 773 | { 774 | this.info := bold 775 | } 776 | ; SetShowInfo() {{{2 777 | SetShowInfo(func) 778 | { 779 | this.ShowInfoFunc := func 780 | } 781 | ; SetHideInfo() {{{2 782 | SetHideInfo(func) 783 | { 784 | this.HideInfoFunc := func 785 | } 786 | ; ShowMore() {{{2 787 | ShowMore() 788 | { 789 | If IsFunc(f:=this.ShowInfoFunc) And this.Info 790 | %f%() 791 | } 792 | ; HideMore() {{{2 793 | HideMore() 794 | { 795 | If IsFunc(f:=this.HideInfoFunc) And this.Info 796 | %f%() 797 | } 798 | } 799 | 800 | ; Class __Mode {{{1 801 | Class __Mode 802 | { 803 | __new(modeName) 804 | { 805 | this.name := modeName 806 | this.keymapList := [] 807 | this.keymoreList := [] 808 | this.nowaitList := [] 809 | this.modeFunction := "" 810 | } 811 | ; SetKeyMap(key,action) {{{2 812 | SetKeyMap(key,action) 813 | { 814 | this.keymapList[key] := action 815 | } 816 | ; GetKeyMap(key) {{{2 817 | GetKeyMap(key) 818 | { 819 | return this.keymapList[key] 820 | } 821 | ; DelKeyMap(key) {{{2 822 | DelKeyMap(key) 823 | { 824 | this.keymapList[key] := "" 825 | } 826 | ; SetNoWait(key,bold) {{{2 827 | ; 无视TimeOut执行热键 828 | SetNoWait(key,bold) 829 | { 830 | this.nowaitList[key] := bold 831 | } 832 | ; GetNoWait(key) {{{2 833 | GetNoWait(key) 834 | { 835 | return this.nowaitList[key] 836 | } 837 | ; SetMoreKey(key) {{{2 838 | SetMoreKey(key) 839 | { 840 | this.keymoreList[key] := true 841 | } 842 | ; GetMoreKey(key) {{{2 843 | GetMoreKey(key) 844 | { 845 | return this.keymoreList[key] 846 | } 847 | } 848 | ; Class __Action {{{1 849 | Class __Action 850 | { 851 | ; Action 有几种类型 852 | ; 0 代表执行Action对应的Label (默认) 853 | ; 1 代表执行Function的值对应的函数 854 | ; 2 代表运行CmdLine对应的值 855 | ; 3 代表发送HotString对应的文本 856 | 857 | __new(Name,Comment){ 858 | this.Name := Name 859 | this.Comment := Comment 860 | this.MaxTimes := 0 861 | this.Type := 0 862 | this.Function := "" 863 | this.CmdLine := "" 864 | this.HotString := "" 865 | } 866 | ; SetFunction(Function) {{{2 867 | ; 设置Action执行的函数名 868 | SetFunction(Function) 869 | { 870 | this.Function := Function 871 | this.Type := 1 872 | } 873 | ; SetCmdLine(CmdLine) {{{2 874 | ; 设置Action运行的字符串 875 | SetCmdLine(CmdLine) 876 | { 877 | this.CmdLine := CmdLine 878 | this.Type := 2 879 | } 880 | ; SetHotString(HotString) {{{2 881 | ; 设置Action发送的文本 882 | SetHotString(HotString) 883 | { 884 | this.HotString := HotString 885 | this.Type := 3 886 | } 887 | ; SetMaxTimes(Times) {{{2 888 | ; 设置最大运行次数 889 | SetMaxTimes(Times) 890 | { 891 | this.MaxTimes := Times 892 | } 893 | ; Do(Times=1) {{{2 894 | ; 执行Action 895 | Do(Times=0) 896 | { 897 | Times := !Times ? 1 : Times 898 | If this.MaxTimes And ( Times > this.MaxTimes) 899 | Times := this.MaxTimes 900 | Loop,%Times% 901 | { 902 | If this.Type = 0 903 | { 904 | If IsLabel(l:=this.Name) 905 | { 906 | GoSub,%l% 907 | return True 908 | } 909 | } 910 | If this.Type = 1 911 | { 912 | If IsFunc(f:=this.Function) 913 | { 914 | %f%() 915 | return True 916 | } 917 | } 918 | If this.Type = 2 919 | { 920 | c := this.CmdLine 921 | Run,%cmd% 922 | return True 923 | } 924 | If This.Type = 3 925 | { 926 | t := this.HotString 927 | Send,%t% 928 | return True 929 | } 930 | } 931 | return False 932 | } 933 | } 934 | 935 | 936 | ; Class __Plugin {{{1 937 | Class __Plugin 938 | { 939 | __new(PluginName) 940 | { 941 | this.PluginName := PluginName 942 | this.Author := "" 943 | this.Ver := "" 944 | this.Comment := "" 945 | } 946 | ; CheckSub() {{{2 947 | CheckSub() 948 | { 949 | If IsLabel(p:=this.PluginName) 950 | { 951 | GoSub,%p% 952 | this.Error := False 953 | } 954 | Else 955 | this.Error := True 956 | } 957 | } 958 | ; Class __vimDebug {{{1 959 | Class __vimDebug 960 | { 961 | __new(key) 962 | { 963 | this.mode := key 964 | If key 965 | { 966 | GUI,vimDebug:Destroy 967 | GUI,vimDebug:+hwnd_vimdebug -Caption +ToolWindow +Border 968 | GUI,vimDebug:color,454545,454545 969 | GUI,vimDebug:font,s16 cFFFFFF 970 | GUI,vimDebug:Add,Edit,x-2 y-2 w400 h60 readonly 971 | GUI,vimDebug:Show, w378 h56 y600 972 | WinSet,AlwaysOnTop,On,ahk_id %_vimdebug% 973 | } 974 | Else 975 | { 976 | GUI,vimDebug:font,s12 977 | GUI,vimDebug:Destroy 978 | GUI,vimDebug:Add,Edit,x10 y10 w400 h300 readonly 979 | GUI,vimDebug:Add,Edit,x10 y320 w400 h26 readonly 980 | GUI,vimDebug:Show, w420 h356 981 | } 982 | } 983 | var(obj) 984 | { 985 | this.vim := obj 986 | } 987 | Set(v) 988 | { 989 | winName := this.vim.CheckWin() 990 | winObj := this.vim.GetWin(winName) 991 | If winObj.Count 992 | k := " 热键缓存:" winObj.Count winObj.KeyTemp 993 | Else 994 | k := " 热键缓存:" winObj.KeyTemp 995 | GUI,vimDebug:Default 996 | GUIControl,,Edit1,%v% 997 | GUIControl,,Edit2,%k% 998 | } 999 | Get() 1000 | { 1001 | GUI,vimDebug:Default 1002 | GUIControlGet,v,,Edit1 1003 | return v 1004 | } 1005 | ; Add(v) {{{2 1006 | Add(v) 1007 | { 1008 | b:=this.Get() 1009 | If this.mode 1010 | this.Set(b) 1011 | else 1012 | this.Set(v "`n" b) 1013 | } 1014 | ; Clear() {{{2 1015 | Clear() 1016 | { 1017 | this.Set("") 1018 | } 1019 | } 1020 | -------------------------------------------------------------------------------- /Lib/dock.ahk: -------------------------------------------------------------------------------- 1 | 2 | ; lib : Dock 3 | ; Ver 2.0 b3 4 | ; author : majkinetor. 5 | Dock(pClientID, pDockDef="", reset=0) { ;Reset is internal parameter, used by Dock_Shutdown 6 | local cnt, new, cx, cy, hx, hY, t, hP 7 | static init=0, idDel, classes="x|y|w|h" 8 | 9 | if (reset) ;Used by Dock Shutdown to reset the function 10 | return init := 0 11 | 12 | if !init 13 | Dock_aClient_0_ := 0 14 | 15 | cnt := Dock_aClient_0_ 16 | 17 | ;remove dock client ? 18 | if (pDockDef="-") and (Dock_%pClientID%){ 19 | 20 | idDel := Dock_%pClientID% 21 | 22 | loop, parse, classes, | 23 | loop, 3 24 | Dock_%pClientID%_%A_LoopField%%A_Index% := "" 25 | Dock_%pClientID% := "" ; don't remove t Dock_%pClientID%_t := 26 | 27 | ;move last one to the place of the deleted one 28 | Dock_aClient_%idDel%_ := Dock_aClient_%cnt%_, Dock_aClient_%cnt%_ := "", Dock_aClient_0_-- 29 | return "OK - Remove" 30 | } 31 | 32 | if pDockDef = 33 | { 34 | WinGetPos hX, hY,,, ahk_id %Dock_HostID% 35 | WinGetPos cX, cY,,, ahk_id %pClientID% 36 | pDockDef := "x(0,0," cX - hX ") y(0,0," cY - hY ")" 37 | } 38 | 39 | ;add new dock client if it not exists, or update its dock settings if it exists 40 | loop, parse, pDockDef, %A_Space%%A_Tab% 41 | if (A_LoopField != "") { 42 | t := A_LoopField, c := SubStr(t,1,1) 43 | if c not in x,y,w,h,t 44 | return "ERR: Bad dock definition" 45 | 46 | if c = t 47 | { 48 | Dock_%pClientID%_t := 1 49 | } 50 | else { 51 | t := SubStr(t,3,-1) 52 | StringReplace, t, t,`,,|,UseErrorLevel 53 | t .= !ErrorLevel ? "||" : (ErrorLevel=1 ? "|" : "") 54 | loop, parse, t,|,%A_Space%%A_Tab% 55 | Dock_%pClientID%_%c%%A_Index% := A_LoopField ? A_LoopField : 0 56 | } 57 | } 58 | 59 | if !Dock_%pClientID% { 60 | Dock_%pClientID% := ++cnt, 61 | Dock_aClient_%cnt%_ := pClientId 62 | Dock_aClient_0_++ 63 | } 64 | 65 | ;start the dock if its not already started 66 | If !init { 67 | init++, Dock_hookProcAdr := RegisterCallback("Dock_HookProc") 68 | Dock_Toggle(true) 69 | } 70 | 71 | Dock_Update() 72 | return "OK" 73 | } 74 | 75 | 76 | ;----------------------------------------------------------------------------------------------------- 77 | ;Function: Dock_Shutdown 78 | ; Uninitialize dock module. This will clear all clients and internal data and unregister hooks. 79 | ; Dock_OnHostDeath, Dock_HostId are kept on user values. 80 | ; 81 | Dock_Shutdown() { 82 | local cID 83 | 84 | Dock_Toggle(false) 85 | DllCall("GlobalFree", "UInt", Dock_hookProcAdr), Dock_hookProcAdr := "" 86 | Dock(0,0,1) ;reset dock function 87 | 88 | ;erase clients 89 | loop, % Dock_aClient_0_ 90 | { 91 | cId := Dock_aClient_%A_Index%_, Dock_aClient_%A_Index%_ := "" 92 | Dock_%cID% := "" 93 | loop, 10 94 | Dock_%cID%_%A_Index% := "" 95 | } 96 | } 97 | 98 | ;----------------------------------------------------------------------------------------------------- 99 | ;Function: Dock_Toggle 100 | ; Toggles the dock module ON or OFF. 101 | ; 102 | ;Parameters: 103 | ; enable - Set to true to set the dock ON, set to FALSE to turn it OFF. Skip to toggle. 104 | ; 105 | ;Remarks: 106 | ; Use Dock_Toggle(false) to suspend the dock module (to unregister hook), leaving its internal data in place. 107 | ; This is different from Dock_Shutdown as latest removes module completely from memory and 108 | ; unregisters its clients. 109 | ; 110 | ; You can also use this function to temporary disable module when you don't want dock update routine to interrupt your time critical sections. 111 | ; 112 | Dock_Toggle( enable="" ) { 113 | global 114 | 115 | if Dock_hookProcAdr = 116 | return "ERR - Dock must be loaded." 117 | 118 | if enable = 119 | enable := !Dock_hHook1 120 | else if (enable && Dock_hHook1) 121 | return "ERR - Dock already enabled" 122 | 123 | if !enable 124 | API_UnhookWinEvent(Dock_hHook1), API_UnhookWinEvent(Dock_hHook2), API_UnhookWinEvent(Dock_hHook3), Dock_hHook3 := Dock_hHook1 := Dock_hHook2 := "" 125 | else { 126 | Dock_hHook1 := API_SetWinEventHook(3,3,0,Dock_hookProcAdr,0,0,0) ; EVENT_SYSTEM_FOREGROUND 127 | Dock_hHook2 := API_SetWinEventHook(0x800B,0x800B,0,Dock_hookProcAdr,0,0,0) ; EVENT_OBJECT_LOCATIONCHANGE 128 | Dock_hHook3 := API_SetWinEventHook(0x8002,0x8003,0,Dock_hookProcAdr,0,0,0) ; EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE 129 | 130 | if !(Dock_hHook1 && Dock_hHook2 && Dock_hHook3) { ;some of them failed, unregister everything 131 | API_UnhookWinEvent(Dock_hHook1), API_UnhookWinEvent(Dock_hHook2), API_UnhookWinEvent(Dock_hHook3) 132 | return "ERR - Hook failed" 133 | } 134 | 135 | Dock_Update() 136 | } 137 | return enable 138 | } 139 | ;==================================== INTERNAL ====================================================== 140 | Dock_Update() { 141 | local hX, hY, hW, hh, W, H, X, Y, cx, cy, cw, ch, fid, wd, cid 142 | static gid=0 ;fid & gid are function id and global id. I use them to see if the function interupted itself. 143 | 144 | wd := A_WinDelay 145 | SetWinDelay, -1 146 | fid := gid += 1 147 | WinGetPos hX, hY, hW, hH, ahk_id %Dock_HostID% 148 | ; OutputDebug %hX% %hY% %hW% %hH% %event% 149 | 150 | ;xhw,xw,xd, yhh,yh,yd, whw,wd, hhh,hd 151 | loop, % Dock_aClient_0_ 152 | { 153 | cId := Dock_aClient_%A_Index%_ 154 | WinGetPos cX, cY, cW, cH, ahk_id %cID% 155 | W := Dock_%cId%_w1*hW + Dock_%cId%_w2, H := Dock_%cId%_h1*hH + Dock_%cId%_h2 156 | X := hX + Dock_%cId%_x1*hW + Dock_%cId%_x2* (W ? W : cW) + Dock_%cId%_x3 157 | Y := hY + Dock_%cId%_y1*hH + Dock_%cId%_y2* (H ? H : cH) + Dock_%cId%_y3 158 | 159 | if (fid != gid) ;some newer instance of the function was running, so just return (function was interupted by itself). Without this, older instance will continue with old host window position and clients will jump to older location. This is not so visible with WinMove as it is very fast, but SetWindowPos shows this in full light. 160 | break 161 | 162 | if dock_resetT 163 | { 164 | dock_resetT := false 165 | DllCall("SetWindowLong", "uint", cId, "int", -8, "uint", 0) 166 | } 167 | DllCall("SetWindowPos", "uint", cId, "uint", 0, "uint", X ? X : cX, "uint", Y ? Y : cY, "uint", W ? W : cW, "uint", H ? H :cH, "uint", 1044) ;4 | 0x10 | 0x400 168 | ; WinMove ahk_id %cId%,,X ? X:"" ,Y ? Y:"", W ? W : "" ,H ? H : "" 169 | } 170 | SetTimer, Dock_SetZOrder, -80 ;set z-order in another thread (protects also from spaming z-order changes when host is rapidly moved). 171 | SetWinDelay, %wd% 172 | } 173 | 174 | Dock_SetZOrder: 175 | ; OutputDebug setzorder 176 | exists := WinExist("ahk_id " Dock_HostID), active := WInExist("A") = Dock_HostId 177 | loop, % Dock_aClient_0_ 178 | { 179 | _ := Dock_aClient_%A_Index%_, _ := Dock_%_%_t 180 | if !_ 181 | DllCall("SetWindowPos", "uint", Dock_aClient_%A_Index%_, "uint", Dock_HostID, "uint", 0, "uint", 0, "uint", 0, "uint", 0, "uint", 19 | 0x4000 | 0x40) 182 | else { 183 | ;Set owned clients if they are not already set. Host may not exist here. 184 | _ := DllCall("GetWindowLong", "uint", Dock_aClient_%A_Index%_, "int", -8) 185 | if !_ and exists 186 | { 187 | dock_resetT := true 188 | DllCall("SetWindowLong", "uint", Dock_aClient_%A_Index%_, "int", -8, "uint", Dock_HostId) 189 | } 190 | 191 | DllCall("SetWindowPos", "uint", Dock_aClient_%A_Index%_, "uint" 192 | , active ? 0 : DllCall("GetWindow", "uint", Dock_HostId, "uint", 3) ;hwndprev 193 | , "uint", 0, "uint", 0, "uint", 0, "uint", 0, "uint", 0x40 | 19 | 0x4000) ;SWP_SHOWWINDOW ..., no activate 194 | 195 | } 196 | } 197 | return 198 | 199 | Dock_SetZOrder_OnClientFocus: 200 | ;OutputDebug setzorder on focus 201 | 202 | ;Set host just bellow focused client. 203 | res := DllCall("SetWindowPos", "uint", Dock_HostID, "uint", Dock_AClient, "uint", 0, "uint", 0, "uint", 0, "uint", 0, "uint", 19) ;SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE ... 204 | 205 | ;Set the non-T children , T children are handled normaly by OS as owned. 206 | loop, % Dock_aClient_0_ 207 | { 208 | _ := Dock_aClient_%A_Index%_, _ := Dock_%_%_t 209 | if !_ 210 | DllCall("SetWindowPos", "uint", Dock_aClient_%A_Index%_, "uint", Dock_HostID, "uint", 0, "uint", 0, "uint", 0, "uint", 0, "uint", 19) ;SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE 211 | } 212 | return 213 | 214 | ;----------------------------------------------------------------------------------------- 215 | ; Events : 216 | ; 3 - Host is set to foreground 217 | ; 32779 - Location change 218 | ; 32770 - Show 219 | ; 32771 - Hide (also called on exit) 220 | ; 221 | Dock_HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime ) { 222 | local e, cls, style 223 | 224 | if idObject or idChild 225 | return 226 | WinGet, style, Style, ahk_id %hwnd% 227 | if (style & 0x40000000) ;RETURN if hwnd is child window, for some reason idChild may be 0 for some children ?!?! ( I hate ms ) 228 | return 229 | 230 | ; WINGETCLASS, cls, ahk_id %hwnd% 231 | ; if cls in #32768,#32771,#32772,#32769,SysShadow,tooltips_class32 ;skip some windows classes, just to speed it up 232 | ; return 233 | 234 | ;outputdebug % cls " " hwnd " " event 235 | if (event = 3) 236 | { 237 | ;check if client is taking focus 238 | loop, % Dock_aClient_0_ 239 | if (hwnd = Dock_aClient_%A_Index%_){ 240 | Dock_AClient := hwnd 241 | gosub Dock_SetZOrder_OnClientFocus 242 | return 243 | } 244 | } 245 | 246 | If (hwnd != Dock_HostID){ 247 | if !WinExist("ahk_id " Dock_HostID) && IsLabel(Dock_OnHostDeath) 248 | { 249 | Dock_Toggle(false) 250 | gosub %Dock_OnHostDeath% 251 | loop, % Dock_aClient_0_ 252 | DllCall("ShowWindow", "uint", Dock_aClient_%A_Index%_, "uint", 0) 253 | } 254 | return 255 | } 256 | 257 | 258 | if event in 32770,32771 259 | { 260 | e := (event - 32771) * -5 261 | loop, % Dock_aClient_0_ 262 | DllCall("ShowWindow", "uint", Dock_aClient_%A_Index%_, "uint", e) 263 | } 264 | 265 | Dock_Update() 266 | ; SetTimer, Dock_Update, -10 267 | } 268 | 269 | Dock_Update: 270 | Dock_Update() 271 | return 272 | 273 | API_SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) { 274 | DllCall("CoInitialize", "uint", 0) 275 | return DllCall("SetWinEventHook", "uint", eventMin, "uint", eventMax, "uint", hmodWinEventProc, "uint", lpfnWinEventProc, "uint", idProcess, "uint", idThread, "uint", dwFlags) 276 | } 277 | 278 | API_UnhookWinEvent( hWinEventHook ) { 279 | return DllCall("UnhookWinEvent", "uint", hWinEventHook) 280 | } 281 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 282 | -------------------------------------------------------------------------------- /Plugins/everything/everything.ahk: -------------------------------------------------------------------------------- 1 | Everything: 2 | vim.SetPlugin("Everything","Array","0.1","用于Everything") 3 | vim.SetAction("EverythingToggle","启用/禁止Everything vim热键") 4 | vim.SetWin("Everything","EVERYTHING") 5 | vim.SetMode("normal","Everything") 6 | vim.map("1","<1>","Everything") 7 | vim.map("2","<2>","Everything") 8 | vim.map("3","<3>","Everything") 9 | vim.map("4","<4>","Everything") 10 | vim.map("5","<5>","Everything") 11 | vim.map("6","<6>","Everything") 12 | vim.map("7","<7>","Everything") 13 | vim.map("8","<8>","Everything") 14 | vim.map("9","<9>","Everything") 15 | vim.map("0","<0>","Everything") 16 | vim.map("j","","Everything") 17 | vim.map("k","","Everything") 18 | vim.map("","EverythingToggle","Everything") 19 | Toggle := True 20 | return 21 | EverythingToggle: 22 | Toggle := Toggle ? False : True 23 | vim.control(Toggle,"Everything") 24 | return 25 | -------------------------------------------------------------------------------- /Plugins/general/general.ahk: -------------------------------------------------------------------------------- 1 | General: 2 | Gen_Save_Win := [] 3 | vim.SetAction("","向下移动") 4 | vim.SetAction("","向上移动") 5 | vim.SetAction("","向左移动") 6 | vim.SetAction("","向右移动") 7 | vim.SetAction("","热键home") 8 | vim.SetAction("","热键End") 9 | vim.SetAction("","向下翻页") 10 | vim.SetAction("","向上翻页") 11 | vim.SetAction("","插入模式") 12 | vim.SetAction("","浏览模式") 13 | vim.SetAction("","启用/禁用vim热键(General插件)") 14 | vim.SetAction("","重新加载") 15 | vim.SetAction("","重新加载") 16 | vim.SetAction("","test") 17 | vim.SetMode("normal") 18 | ;vim.map("","") 19 | vim.map("","") 20 | ;vim.map("dddd","") 21 | 22 | vim.SetWin("General","General") 23 | vim.SetMode("insert","General") 24 | vim.map("","","General") 25 | vim.SetMode("normal","General") 26 | vim.Map("j","","General") 27 | vim.Map("k","","General") 28 | vim.Map("l","","General") 29 | vim.Map("h","","General") 30 | vim.Map("gw","","General") 31 | vim.map("i","","General") 32 | ;vim.Map("","HotkeyToggle","General") 33 | return 34 | 35 | : 36 | vim.SetMode("Insert",vim.CheckWin()) 37 | return 38 | : 39 | vim.SetMode("Normal",vim.CheckWin()) 40 | return 41 | : 42 | Gen_Toggle() 43 | return 44 | Gen_Toggle() 45 | { 46 | Global vim, Gen_Save_Win 47 | WinGetClass,c,A 48 | WinName:=vim.CheckWin() 49 | If not Gen_Save_Win[c] 50 | { 51 | If Strlen(winName) And IsObject(vim.GetWin(winName)) 52 | { 53 | MsgBox, ,VimDesktop, 当前窗口 [ %winName% ] 已经拥有Vim模式`n不允许替换为通用(General)模式! 54 | return 55 | } 56 | } 57 | winObj := vim.GetWin(c) 58 | If not Isobject(winObj) 59 | { 60 | new :=vim.copy("General",c,c) 61 | Gen_Save_Win[c] := True 62 | } 63 | Else 64 | vim.Toggle(c) 65 | } 66 | : 67 | msgbox 是否是这个效果? 68 | return 69 | : 70 | reload 71 | return 72 | : 73 | ExitApp 74 | return 75 | : 76 | send,{down} 77 | return 78 | : 79 | send,{up} 80 | return 81 | : 82 | send,{left} 83 | return 84 | : 85 | send,{right} 86 | return 87 | : 88 | send,{home} 89 | return 90 | : 91 | send,{end} 92 | return 93 | : 94 | send,{pgup} 95 | return 96 | : 97 | send,{pgdown} 98 | return 99 | -------------------------------------------------------------------------------- /Plugins/totalcmd/a-zhistory.icl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxinhong/VimDesktop/2b367ca7fb7a7bffdecdcbc5155270b636d3d10b/Plugins/totalcmd/a-zhistory.icl -------------------------------------------------------------------------------- /Plugins/totalcmd/totalcmd.ahk: -------------------------------------------------------------------------------- 1 | ; TOTALCMD: {{{1 2 | TOTALCMD: 3 | vim.SetPlugin("TOTALCOMMANDER","Array","0.2","TC管理器插件,前身是(VIATC)") 4 | TCPluginINI := A_ScriptDir "\plugins\TOTALCMD\totalcmd.ini" 5 | TCExe:=GetTCINI("TCexe") 6 | TCCtrl:=GetTCCtrl() 7 | SetTCINI("TCDir",TCDir:=GetTCDir()) 8 | SetTCINI("TCExe",TCExe) 9 | TCINI:=RegExMatch(TCDir,"\\$") ? TCDir "wincmd.ini" : TCDir "\wincmd.ini" 10 | hittext:=GetHitText("ASDFJKLGHQCMPI") 11 | GoSub,LoadTCActions 12 | GoSub,TCCOMMAND 13 | vim.SetMode("normal") 14 | vim.Map("","") 15 | vim.SetWin("TC","TTOTAL_CMD",TCExe) 16 | vim.SetTimeOut(800,"TC") 17 | vim.BeforeActionDo("TC_BeforeActionDo","TC") 18 | vim.AfterActionDo("TC_AfterActionDo","TC") 19 | ;====设置 normal 模式 ==== 20 | vim.SetMode("normal","TC") 21 | vim.Map("0","<0>","TC") 22 | vim.Map("1","<1>","TC") 23 | vim.Map("2","<2>","TC") 24 | vim.Map("3","<3>","TC") 25 | vim.Map("4","<4>","TC") 26 | vim.Map("5","<5>","TC") 27 | vim.Map("6","<6>","TC") 28 | vim.Map("7","<7>","TC") 29 | vim.Map("8","<8>","TC") 30 | vim.Map("9","<9>","TC") 31 | vim.Map("j","","TC") 32 | vim.Map("k","","TC") 33 | vim.Map("h","","TC") 34 | vim.Map("l","","TC") 35 | vim.map("H","","TC") 36 | vim.map("L","","TC") 37 | vim.map("J","","TC") 38 | vim.map("K","","TC") 39 | vim.map("d","","TC") 40 | vim.map("D","","TC") 41 | vim.map("e","","TC") 42 | vim.map("E","","TC") 43 | vim.map("N","","TC") 44 | vim.map("o","","TC") 45 | vim.map("O","","TC") 46 | vim.map("q","","TC") 47 | vim.map("r","","TC") 48 | vim.map("R","","TC") 49 | vim.map("x","","TC") 50 | vim.map("X","","TC") 51 | vim.map("w","","TC") 52 | vim.map("y","","TC") 53 | vim.map("Y","","TC") 54 | vim.map("p","","TC") 55 | vim.map("P","","TC") 56 | vim.map("t","","TC") 57 | vim.map("u","","TC") 58 | vim.map("U","","TC") 59 | vim.map("T","","TC") 60 | vim.map("/","","TC") 61 | vim.map("?","","TC") 62 | vim.map("[","","TC") 63 | vim.map("{","","TC") 64 | vim.map("]","","TC") 65 | vim.map("{","","TC") 66 | vim.map("\","","TC") 67 | vim.map("|","","TC") 68 | vim.map("-","","TC") 69 | vim.map("=","","TC") 70 | vim.map(";","","TC") 71 | vim.map("cc","","TC") 72 | vim.map("co","","TC") 73 | vim.map("cs","","TC") 74 | vim.map("cb","","TC") 75 | vim.map("ct","","TC") 76 | vim.map("cv","","TC") 77 | ;vim.map("G","","TC") 78 | ;vim.map("gg","","TC") 79 | ;vim.map("g$","","TC") 80 | vim.map("ga","","TC") 81 | vim.map("gn","","TC") 82 | vim.map("gp","","TC") 83 | vim.map("gc","","TC") 84 | vim.map("gb","","TC") 85 | vim.map("ge","","TC") 86 | vim.map("gw","","TC") 87 | vim.map("g1","","TC") 88 | vim.map("g2","","TC") 89 | vim.map("g3","","TC") 90 | vim.map("g4","","TC") 91 | vim.map("g5","","TC") 92 | vim.map("g6","","TC") 93 | vim.map("g7","","TC") 94 | vim.map("g8","","TC") 95 | vim.map("g9","","TC") 96 | vim.map("sn","","TC") 97 | vim.map("se","","TC") 98 | vim.map("ss","","TC") 99 | vim.map("sd","","TC") 100 | vim.map("sr","","TC") 101 | vim.map("s1","","TC") 102 | vim.map("s2","","TC") 103 | vim.map("s3","","TC") 104 | vim.map("s4","","TC") 105 | vim.map("s5","","TC") 106 | vim.map("s6","","TC") 107 | vim.map("s7","","TC") 108 | vim.map("s8","","TC") 109 | vim.map("s9","","TC") 110 | vim.map("s0","","TC") 111 | vim.map("v","","TC") 112 | vim.map("Vb","","TC") 113 | vim.map("Vd","","TC") 114 | vim.map("Vo","","TC") 115 | vim.map("Vr","","TC") 116 | vim.map("Vc","","TC") 117 | vim.map("Vt","","TC") 118 | vim.map("Vs","","TC") 119 | vim.map("Vn","","TC") 120 | vim.map("Vf","","TC") 121 | vim.map("Vw","","TC") 122 | vim.map("Ve","","TC") 123 | vim.map("zz","","TC") 124 | ;vim.map("zi","","TC") 125 | ;vim.map("zo","","TC") 126 | vim.map("zt","","TC") 127 | vim.map("zn","","TC") 128 | vim.map("zm","","TC") 129 | vim.map("zr","","TC") 130 | vim.map("zv","","TC") 131 | 132 | ;vim.map("g0","","TC") 133 | ;vim.map("m","","TC") 134 | ;vim.map("'","","TC") 135 | ;vim.Map("g","","TC") 136 | vim.Map("n","","TC") 137 | vim.Map("i","","TC") 138 | vim.Map(":","","TC") 139 | vim.Map("","","TC") 140 | ;========================= 141 | 142 | ;====设置 Insert 模式 ==== 143 | vim.SetMode("insert","TC") 144 | vim.Map("","","TC") 145 | ;========================= 146 | 147 | ;====设置 Edit 模式 ==== 148 | vim.SetMode("CMD","TC") 149 | vim.Map("","","TC") 150 | ;========================= 151 | 152 | ;====设置 Hint 模式 ==== 153 | vim.SetMode("Hint","TC") 154 | vim.Map("","","TC") 155 | ;========================= 156 | 157 | ;====设置 Search 模式 ==== 158 | vim.SetMode("Search","TC") 159 | vim.Map("","","TC") 160 | ;========================= 161 | 162 | ;====设置 History 模式 ==== 163 | vim.SetMode("History","TC") 164 | Loop,26 165 | { 166 | ;vim.Map(chr(64+A_Index),"","TC") 167 | vim.Map(chr(96+A_Index),"","TC") 168 | } 169 | ;========================= 170 | 171 | ; 设置初始化为 normal 模式 172 | vim.SetMode("normal","TC") 173 | return 174 | 175 | ; LoadTCActions: {{{1 176 | LoadTCActions: 177 | vim.SetAction("","向下移动") 178 | vim.SetAction("","向上移动") 179 | vim.SetAction("","向左移动") 180 | vim.SetAction("","向右移动") 181 | vim.SetAction("","向下选择") 182 | vim.SetAction("","向上选择") 183 | vim.SetAction("","强制删除") 184 | vim.SetAction("","返回上一级") 185 | vim.SetAction("","置顶TC") 186 | 187 | vim.SetAction("","激活TC") 188 | vim.SetAction("","切换为Normal模式,并发送Esc") 189 | vim.SetAction("","切换为Insert模式") 190 | vim.SetAction("","切换为CMD模式") 191 | vim.SetAction("","Hint模式") 192 | vim.SetAction("","Hint历史记录") 193 | vim.SetAction("","az历史记录") 194 | vim.SetAction("","az历史点击") 195 | return 196 | ; TC_BeforeActionDo() {{{1 197 | TC_BeforeActionDo() 198 | { 199 | Global TCCtrl,TC_SendPos 200 | WinGet,MenuID,ID,AHK_CLASS #32768 201 | If MenuID And (TC_SendPos <> 572) 202 | return True 203 | ControlGetFocus,ctrl,AHK_CLASS TTOTAL_CMD 204 | TCListBox := TCCtrl["TCListBox"] 205 | Ifinstring,ctrl,%TCListBox% 206 | Return False 207 | Return True 208 | } 209 | ; TC_AfterActionDo() {{{1 210 | TC_AfterActionDo() 211 | { 212 | TC_Dock_Init() 213 | } 214 | TC_Dock_Init() 215 | { 216 | Global vim 217 | TC_Dock_Load() 218 | modeObj := vim.GetMode("TC") 219 | If RegExMatch(modeObj.name,"i)^CMD$") 220 | { 221 | GUI,TC_Dock:Default 222 | GUIControlGet,vis,Visible,Edit1 223 | If vis 224 | GUIControl,Focus,Edit1 225 | Else 226 | TC_Dock_EditUpdate() 227 | } 228 | Else 229 | TC_Dock_TextUpdate() 230 | } 231 | TC_DockGuiEscape: 232 | vim.SetMode("normal","TC") 233 | WinActivate,ahk_class TTOTAL_CMD 234 | TC_Dock_TextUpdate() 235 | return 236 | TC_Dock_Edit_Change: 237 | GUI,TC_Dock:Default 238 | GUIControlGet,string,,Edit1 239 | If not Strlen(string) 240 | GoSub,TC_DockGuiEscape 241 | return 242 | TC_Dock_Edit_OK: 243 | TC_Dock_Edit_OK() 244 | return 245 | ; TC_Dock_Edit_OK() {{{2 246 | TC_Dock_Edit_OK() 247 | { 248 | GUI,TC_Dock:Default 249 | GUIControlGet,string,,Edit1 250 | If RegExMatch(string,"i)^:[e|(ex)|(exi)|(exit)][\s]*") 251 | WinClose,ahk_Class TTOTAL_CMD 252 | Else If RegExMatch(string,"i)^:set") { 253 | SetString := SubStr(String,5) 254 | If RegExMatch(SetString,"i)\s*sb\s*=\s*([01])\s*$",m) { 255 | If not m1 256 | TC_Dock_Destroy() 257 | SetTCINI("sb",m1) 258 | } 259 | Else If RegExMatch(SetString,"i)\s*sb_[l|(le)|(len)]\s*=\s*(\d+)\s*$",m) { 260 | If m1 < 100 261 | m1 := 100 262 | SetTCINI("sb_len",m1) 263 | TC_Dock_Destroy() 264 | TC_Dock_Load() 265 | TC_Dock_TextUpdate() 266 | } 267 | Else If RegExMatch(SetString,"i)\s*sb_[b|(bc)|(bco)|(bcol)|(bcolo)|(bcolor)]\s*=\s*([\dA-Fa-f]+)\s*$",m) { 268 | SetTCINI("sb_bcolor",m1) 269 | TC_Dock_Destroy() 270 | TC_Dock_Load() 271 | TC_Dock_TextUpdate() 272 | } 273 | Else If RegExMatch(SetString,"i)\s*sb_[t|(tc)|(tco)|(tcol)|(tcolo)|(tcolor)]\s*=\s*([\dA-Fa-f]+)\s*$",m) { 274 | SetTCINI("sb_tcolor",m1) 275 | TC_Dock_Destroy() 276 | TC_Dock_Load() 277 | TC_Dock_TextUpdate() 278 | } 279 | Else If RegExMatch(SetString,"i)\s*sb_[s|(st)|(str)|(stri)|(strin)|(string)]\s*=(.*)$",m) 280 | { 281 | SetTCINI("sb_String",m1) 282 | TC_Dock_Destroy() 283 | TC_Dock_Load() 284 | TC_Dock_TextUpdate() 285 | } 286 | } 287 | Else If RegExMatch(string,"i)^:(h|(he)|(hel)|(help))$") { 288 | msgbox help 289 | } 290 | Else 291 | Error := True 292 | GoSub,TC_DockGuiEscape 293 | If Error { 294 | GUI,TC_Dock:Default 295 | GUIControl,,Static1,!!! Command Error 296 | } 297 | } 298 | ; TC_Dock_TextUpdate() {{{2 299 | TC_Dock_TextUpdate() 300 | { 301 | winObj := vim.GetWin("TC") 302 | modeObj := vim.GetMode("TC") 303 | name := modeObj.name 304 | StringUpper, name , name , T 305 | string := (s:=GetTCINI("sb_String")) ? s : "-- -- " 306 | string := RegExReplace(string,"i)",name) 307 | string := RegExReplace(string,"i)",winObj.KeyTemp) 308 | count := winObj.Count ? winObj.Count : "" 309 | string := RegExReplace(string,"i)",Count) 310 | ;name := "-- " name " -- " winObj.KeyTemp 311 | GUI,TC_Dock:Default 312 | GUIControl,-g,Edit1 313 | GUIControl,Hide,Edit1 314 | GUIControl,Show,Static1 315 | GUIControl,,Static1,%string% 316 | } 317 | ; TC_Dock_EditUpdate() {{{2 318 | TC_Dock_EditUpdate() 319 | { 320 | GUI,TC_Dock:Default 321 | GUI,TC_Dock:+hwndhTC_Dock 322 | GUIControl,Hide,Static1 323 | GUIControl,Show,Edit1 324 | GUIControl,,Edit1 325 | GUIControl,Focus,Edit1 326 | ControlSend,Edit1,:,ahk_id %hTC_Dock% 327 | GUIControl,+gTC_Dock_Edit_Change,Edit1 328 | } 329 | ; TC_Dock_Destroy() {{{2 330 | TC_Dock_Destroy(){ 331 | Global Dock_HostID 332 | GUI,TC_Dock:Destroy 333 | Dock_HostID := 0 334 | } 335 | ; TC_Dock_Load() {{{2 336 | TC_Dock_Load(){ 337 | Global Dock_HostID 338 | s:=strlen(s:=GetTCINI("sb")) ? s : True 339 | If Not Dock_HostID And s 340 | { 341 | Dock_HostID := WinExist("ahk_class TTOTAL_CMD") 342 | length := (l:=GetTCINI("sb_len")) ? l : 240 343 | bcolor := (b:=GetTCINI("sb_bcolor")) ? b : 454545 344 | tcolor := (c:=GetTCINI("sb_tcolor")) ? c : "FFFFFF" 345 | font := (f:=GetTCINI("sb_font")) ? f : 12 346 | hight := (h:=GetTCINI("sb_hight")) ? h : 24 347 | hight2 := hight+4 348 | length2 := length+10 349 | m := ceil((hight-font)/2)-2 350 | GUI,TC_Dock:Destroy 351 | GUI,TC_Dock:+LastFound -Caption +ToolWindow +Border 352 | GUI,TC_Dock:color,%bcolor%,%bcolor% 353 | GUI,TC_Dock:font,s%font% c%tcolor% 354 | GUI,TC_Dock:Add, Text, y%m% x5 w%length% h%hight% 355 | GUI,TC_Dock:Add, Edit, y-2 x-2 w%length2% h%hight2% hidden -Multi 356 | GUI,TC_Dock:Add, Button, Default w0 h0 WantReturn gTC_Dock_Edit_OK 357 | GUI,TC_Dock:Show 358 | Dock(WinExist(), "x(0,0,10) y(1,-1,-10) w(0," length ") h(0," hight ") t", 0) 359 | Winactivate,AHK_CLASS TTOTAL_CMD 360 | } 361 | } 362 | 363 | 364 | GetTCDir() 365 | { 366 | Global TCPluginINI 367 | If FileExist(TCDir:=GetTCINI("TCDir")) 368 | return TCDir 369 | IfWinExist ahk_class TTOTAL_CMD 370 | WinGet,TCPath,ProcessPath,ahk_class TTOTAL_CMD 371 | If FileExist(TCPath) 372 | { 373 | Splitpath,TCPath,,TCDir 374 | return TCDir 375 | } 376 | RegRead,TCDir,HKEY_CURRENT_USER,Software\Ghisler\Total Commander,InstallDir 377 | If FileExist(TCDir) 378 | return TCDir 379 | } 380 | GetTCINI(k) 381 | { 382 | Global TCPluginINI 383 | INIRead,r,%TCPluginINI%,Config,%k%,%A_Space% 384 | return r 385 | } 386 | SetTCINI(k,v) 387 | { 388 | Global TCPluginINI 389 | INIWrite,%v%,%TCPluginINI%,config,%k% 390 | } 391 | FindTCDir() 392 | { 393 | Global TCDir 394 | GUI,FindTCDir:Destroy 395 | GUI,FindTCDir:Add,Edit,w300 ReadOnly,%TCDir% 396 | GUI,FindTCDir:show 397 | } 398 | GetTCCtrl() 399 | { 400 | Global TCExe 401 | ctrl := [] 402 | If RegExMatch(TCExe,"i)64\.exe") 403 | { 404 | ctrl["TCListBox"] := "LCLListBox" 405 | ctrl["TCEdit"] := "Edit1" 406 | ctrl["TInEdit"] := "Edit1" 407 | ctrl["TCPanel1"] := "Window1" 408 | ctrl["TCPanel2"] := "Window11" 409 | } 410 | Else 411 | { 412 | ctrl["TCListBox"] := "TMyListBox" 413 | ctrl["TCEdit"] := "Edit1" 414 | ctrl["TInEdit"] := "TInEdit1" 415 | ctrl["TCPanel1"] := "TPanel1" 416 | ctrl["TCPanel2"] := "TMyPanel8" 417 | } 418 | return ctrl 419 | } 420 | ; TC Actions {{{1 421 | ; : {{{2 422 | : 423 | vim.Clear("TC") 424 | vim.SetMode("normal","TC") 425 | return 426 | ; : {{{2 427 | : 428 | vim.Clear("TC") 429 | vim.SetMode("insert","TC") 430 | return 431 | ; : {{{2 432 | : 433 | vim.Clear("TC") 434 | vim.SetMode("search","TC") 435 | return 436 | ; : {{{2 437 | : 438 | vim.Clear("TC") 439 | vim.SetMode("CMD","TC") 440 | return 441 | ; : {{{2 442 | : 443 | Send,{Esc} 444 | vim.Clear("TC") 445 | vim.SetMode("normal","TC") 446 | return 447 | ; : {{{2 448 | : 449 | send,{down} 450 | return 451 | ; : {{{2 452 | : 453 | send,{up} 454 | return 455 | ; : {{{2 456 | : 457 | send,{left} 458 | return 459 | ; : {{{2 460 | : 461 | send,{right} 462 | return 463 | ; : {{{2 464 | : 465 | send,+{Down} 466 | return 467 | ; : {{{2 468 | : 469 | send,+{Up} 470 | return 471 | ; : {{{2 472 | : 473 | send,+{Delete} 474 | return 475 | ; {{{2 476 | ; 返回到上层文件夹,可返回到我的电脑 477 | : 478 | IsRootDir() 479 | GoSub, 480 | return 481 | IsRootDir() 482 | { 483 | ClipSaved := ClipboardAll 484 | clipboard := 485 | GoSub, 486 | ClipWait,1 487 | Path := Clipboard 488 | Clipboard := ClipSaved 489 | If RegExMatch(Path,"^.:\\$") 490 | { 491 | GoSub, 492 | Path := "i)" . RegExReplace(Path,"\\","") 493 | ControlGetFocus,focus_control,AHK_CLASS TTOTAL_CMD 494 | ControlGet,outvar,list,,%focus_control%,AHK_CLASS TTOTAL_CMD 495 | Loop,Parse,Outvar,`n 496 | { 497 | If Not A_LoopField 498 | Break 499 | If RegExMatch(A_LoopField,Path) 500 | { 501 | Focus := A_Index - 1 502 | Break 503 | } 504 | } 505 | PostMessage, 0x19E, %Focus%, 1, %focus_control%, AHK_CLASS TTOTAL_CMD 506 | } 507 | } 508 | ; : {{{2 509 | : 510 | AlwayOnTop() 511 | Return 512 | AlwayOnTop() 513 | { 514 | WinGet,ExStyle,ExStyle,ahk_class TTOTAL_CMD 515 | If (ExStyle & 0x8) 516 | WinSet,AlwaysOnTop,off,ahk_class TTOTAL_CMD 517 | else 518 | WinSet,AlwaysOnTop,on,ahk_class TTOTAL_CMD 519 | } 520 | 521 | ; : {{{2 522 | : 523 | TC_Toggle() 524 | return 525 | TC_Toggle() 526 | { 527 | Global TCDir,TCExe,Dock_HostID 528 | TCPath:= RegExMatch(TCDir,"\\$") ? TCDir TCExe : TCDir "\" TCExe 529 | IfWinExist,AHK_CLASS TTOTAL_CMD 530 | { 531 | WinGet,AC,MinMax,AHK_CLASS TTOTAL_CMD 532 | If Ac = -1 533 | Winactivate,AHK_ClASS TTOTAL_CMD 534 | Else 535 | Ifwinnotactive,AHK_CLASS TTOTAL_CMD 536 | Winactivate,AHK_CLASS TTOTAL_CMD 537 | Else 538 | Winminimize,AHK_CLASS TTOTAL_CMD 539 | } 540 | Else 541 | { 542 | Dock_HostID := 0 543 | Run,%TCPath% 544 | Loop,4 545 | { 546 | IfWinNotActive,AHK_CLASS TTOTAL_CMD 547 | WinActivate,AHK_CLASS TTOTAL_CMD 548 | Else 549 | Break 550 | Sleep,500 551 | } 552 | } 553 | TC_Dock_Init() 554 | } 555 | 556 | ; : {{{2 557 | : 558 | vim.SetMode("Hint","TC") 559 | msgbox Hint 560 | return 561 | ; : {{{2 562 | : 563 | TC_HintHistory() 564 | vim.SetMode("History","TC") 565 | return 566 | TC_HintHistory() 567 | { 568 | Global HitText,HitText_a2z,HitLocation,hHistory ;,graphics,brush,pen,pToken,hbm,hdc,obm,hHistory 569 | Global hithwnd,hdc,Width,Height 570 | GoSub, 571 | WinWait, ahk_class #32768 572 | hHistory:=WinExist("ahk_class #32768") 573 | SendMessage, 0x1E1, 0, 0 ; MN_GETHMENU 574 | SetTimer,Check_TCHistory,200 575 | hMenu := ErrorLevel 576 | GoSub,TC_Hint_On 577 | HitLocation:=[] 578 | HitText[0]:=0 579 | HitText_a2z := 0 580 | Loop,% GetMenuItemCount(hMenu) 581 | { 582 | pos := GetMenuItemRect(hMenu,A_Index-1) 583 | DrawHit_a2z(pos.x,pos.y+2) 584 | } 585 | UpdateLayeredWindow(hithwnd, hdc, 0, 0, Width, Height) 586 | } 587 | Check_TCHistory: 588 | If not WinExist("ahk_id " hHistory) 589 | { 590 | Settimer,Check_TCHistory,off 591 | vim.SetMode("normal","TC") 592 | GoSub,TC_Hint_Off 593 | TC_AfterActionDo() 594 | } 595 | return 596 | : 597 | TC_HintHistory_Click() 598 | return 599 | TC_HintHistory_Click() 600 | { 601 | Global HitLocation,vim 602 | pos := HitLocation[A_ThisHotkey] 603 | x := pos["x"]+5 604 | y := pos["y"] 605 | SendClick(x,y) 606 | vim.SetMode("normal","TC") 607 | GoSub,TC_Hint_Off 608 | } 609 | SendClick(x,y) 610 | { 611 | CoordMode,Mouse,Screen 612 | d := A_MouseDelay 613 | MouseGetPos,bx,by 614 | SetMouseDelay,-1 615 | Click,%x%,%y% 616 | Click,%bx%,%by%,0 617 | SetMouseDelay,%d% 618 | } 619 | TC_Hint_On: 620 | { 621 | If !pToken := Gdip_StartUp() 622 | return 623 | Width := A_ScreenWidth , Height := A_ScreenHeight 624 | Gui,hitwin: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop 625 | Gui,hitwin: Show, NA 626 | hithwnd := WinExist() 627 | hbm := CreateDIBSection(Width, Height) 628 | hdc := CreateCompatibleDC() 629 | obm := SelectObject(hdc, hbm) 630 | graphics := Gdip_GraphicsFromHDC(hdc) 631 | Gdip_SetSmoothingMode(graphics, 4) 632 | brush := Gdip_BrushCreateSolid(0xFFf8f640) 633 | pen := Gdip_CreatePen(0xFFd05080,1) 634 | return 635 | } 636 | 637 | TC_Hint_Off: 638 | { 639 | If pToken 640 | { 641 | Gdip_DeletePen(pPen) 642 | Gdip_DeleteBrush(b) 643 | SelectObject(hdc, obm) 644 | DeleteObject(hbm) 645 | DeleteDC(hdc) 646 | Gdip_DeleteGraphics(G) 647 | Gdip_Shutdown(pToken) 648 | GUI,hitwin:Destroy 649 | } 650 | return 651 | } 652 | 653 | GetAccLocation(AccObj, Child=0, byref x="", byref y="", byref w="", byref h="") 654 | { 655 | AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), Child) 656 | return "x" (x:=NumGet(x,0,"int")) " " 657 | . "y" (y:=NumGet(y,0,"int")) " " 658 | . "w" (w:=NumGet(w,0,"int")) " " 659 | . "h" (h:=NumGet(h,0,"int")) 660 | } 661 | DrawHit(x,y) 662 | { 663 | global HitText,HitLocation,graphics,brush,pen 664 | idx:=HitText[0]:=HitText[0]+1 665 | n:= strlen(t:=HitText[idx]) > 1 ? 28 : 18 666 | HitLocation[t]:={"x":x,"y":y} 667 | Gdip_FillRoundedRectangle(graphics, brush, x, y, n, 16, 3) 668 | Gdip_DrawRoundedRectangle(graphics, pen, x, y, n, 16,3) 669 | Gdip_TextToGraphics(graphics,t,"x" x+3 " y" y+2 " h16 w" n) 670 | return 671 | } 672 | DrawHit_a2z(x,y) 673 | { 674 | global graphics,brush,pen,HitText_a2z,HitLocation 675 | n := 18 676 | HitText_a2z++ 677 | HitLocation[Chr(64+HitText_a2z)]:={"x":x,"y":y} 678 | Gdip_FillRoundedRectangle(graphics, brush, x, y, n, 16, 3) 679 | Gdip_DrawRoundedRectangle(graphics, pen, x, y, n, 16,3) 680 | Gdip_TextToGraphics(graphics,Chr(64+HitText_a2z),"x" x+3 " y" y+2 " h16 w" n) 681 | } 682 | GetHitText(string) 683 | { 684 | text := [] 685 | l:=strlen(string)-8 686 | idx:=m:=n:=1 687 | Loop,8 688 | { 689 | c := SubStr(string,idx,1) 690 | StringUpper,c,c 691 | text[idx] := c 692 | idx++ 693 | } 694 | String:=SubStr(string,9) 695 | s:=SubStr(string,1,1) 696 | Loop,999 697 | { 698 | c := SubStr(string,n,1) 699 | StringUpper,c,c 700 | text[idx] := s c 701 | idx++ 702 | n++ 703 | if n >= %l% 704 | { 705 | s:= subStr(string,m,1) 706 | StringUpper,s,s 707 | m++ 708 | n:= 1 709 | } 710 | } 711 | return text 712 | } 713 | 714 | GetMenuItemCount(hMenu){ 715 | return DllCall("GetMenuItemCount", "Uint", hMenu) 716 | } 717 | GetMenuItemID(hmenu,idx){ 718 | ; 当前菜单为子菜单时,返回-1 719 | return DllCall("GetMenuItemID", "Uint", hMenu, "Uint", idx) 720 | } 721 | GetMenuItemRect(hMenu,idx){ 722 | VarSetCapacity(rect,16) 723 | DllCall("GetMenuItemRect", "Uint" , 0, "Uint", hMenu, "int", idx, "ptr", &rect) 724 | r := [] 725 | r.x := NumGet(rect,0,true) 726 | r.y := NumGet(rect,4,true) 727 | r.w := NumGet(rect,8,true) 728 | r.h := NumGet(rect,12,true) 729 | return r 730 | } 731 | GetMenuString(hMenu,idx){ 732 | nSize++ := DllCall("GetMenuString", "Uint", hMenu, "int", idx, "Uint", 0, "int", 0, "Uint", 0x400) 733 | VarSetCapacity(sString, nSize) 734 | DllCall("GetMenuString", "Uint", hMenu, "int", idx, "str", sString, "int", nSize, "Uint", 0x400) ;MF_BYPOSITION 735 | return sString 736 | } 737 | GetSubMenu(hMenu,idx){ 738 | return DllCall("GetSubMenu", "Uint", hMenu, "int", idx) 739 | } 740 | GetMenu(hMenu) 741 | { 742 | Loop, % GetMenuItemCount(hMenu) 743 | { 744 | idx := A_Index - 1 745 | idn := GetMenuItemID(hMenu,idx) 746 | sString := GetMenuString(hMenu,idx) 747 | rect := GetMenuItemRect(hmenu,idx) 748 | If !sString 749 | sString := "---------------------------------------" 750 | sContents .= idx . " : " . idn . A_Tab . A_Tab . sString . " rect : (x:" rect.x ")(y:" rect.y ")(w:" rect.w ")(h:" rect.h . ")`n" 751 | If (idn = -1) && (hSubMenu := GetSubMenu(hMenu,idx)) 752 | sContents .= GetMenu(hSubMenu) 753 | } 754 | Return sContents 755 | } 756 | ; : {{{2 757 | : 758 | TC_GoToDesktop() 759 | return 760 | TC_GoToDesktop() 761 | { 762 | ; GoSub, 763 | SendMessage 1075, 4003, 0, , AHK_CLASS TTOTAL_CMD 764 | ControlGetFocus,cl,ahk_class TTOTAL_CMD 765 | ControlGetText,bt,%cl%,AHK_CLASS TTOTAL_CMD 766 | ControlSetText, %cl%, cd %A_Desktop%, ahk_class TTOTAL_CMD 767 | ControlSend,%cl%, {Enter}, ahk_class TTOTAL_CMD 768 | ControlSetText, %cl%, %bt%, ahk_class TTOTAL_CMD 769 | ControlSend,%cl%, {end}, ahk_class TTOTAL_CMD 770 | } 771 | ; Tool Functions {{{1 772 | ; LeftRight(){{{2 773 | LeftRight(){ 774 | ControlGetFocus,TLB,ahk_class TTOTAL_CMD 775 | ControlGetPos,x2,y2,wn,,%TLB%,ahk_class TTOTAL_CMD 776 | ControlGetPos,x1,y1,,,%TCPanel1%,AHK_CLASS TTOTAL_CMD 777 | If x1 > %y1% 778 | { 779 | ; 左右窗口 780 | If x1 > %x2% 781 | return True 782 | Else 783 | return False 784 | } 785 | Else 786 | { 787 | ; 上下窗口 788 | If y1 > %y2% 789 | return True 790 | Else 791 | return False 792 | } 793 | } 794 | 795 | ; TC自带命令 {{{1 796 | ;================================================== 797 | ;=======使用VIM下的VOom 插件可以很方便的查看======= 798 | ;================================================== 799 | TCCOMMAND: 800 | vim.SetAction("","来源窗口: 显示文件备注") 801 | vim.SetAction("","来源窗口: 列表") 802 | vim.SetAction("","来源窗口: 详细信息") 803 | vim.SetAction("","来源窗口: 文件夹树") 804 | vim.SetAction("","来源窗口: 快速查看") 805 | vim.SetAction("","纵向/横向排列") 806 | vim.SetAction("","来源窗口: 快速查看(不用插件)") 807 | vim.SetAction("","来源窗口: 关闭快速查看窗口") 808 | vim.SetAction("","来源窗口: 可执行文件") 809 | vim.SetAction("","来源窗口: 所有文件") 810 | vim.SetAction("","来源窗口: 上次选中的文件") 811 | vim.SetAction("","来源窗口: 自定义类型") 812 | vim.SetAction("","来源窗口: 按文件名排序") 813 | vim.SetAction("","来源窗口: 按扩展名排序") 814 | vim.SetAction("","来源窗口: 按大小排序") 815 | vim.SetAction("","来源窗口: 按日期时间排序") 816 | vim.SetAction("","来源窗口: 不排序") 817 | vim.SetAction("","来源窗口: 反向排序") 818 | vim.SetAction("","来源窗口: 打开驱动器列表") 819 | vim.SetAction("","来源窗口: 缩略图") 820 | vim.SetAction("","来源窗口: 自定义视图菜单") 821 | vim.SetAction("","来源窗口: 焦点置于路径上") 822 | vim.SetAction("","左窗口: 显示文件备注") 823 | vim.SetAction("","左窗口: 列表") 824 | vim.SetAction("","左窗口: 详细信息") 825 | vim.SetAction("","左窗口: 文件夹树") 826 | vim.SetAction("","左窗口: 快速查看") 827 | vim.SetAction("","左窗口: 快速查看(不用插件)") 828 | vim.SetAction("","左窗口: 关闭快速查看窗口") 829 | vim.SetAction("","左窗口: 可执行文件") 830 | vim.SetAction(""," 左窗口: 所有文件") 831 | vim.SetAction("","左窗口: 上次选中的文件") 832 | vim.SetAction("","左窗口: 自定义类型") 833 | vim.SetAction("","左窗口: 按文件名排序") 834 | vim.SetAction("","左窗口: 按扩展名排序") 835 | vim.SetAction("","左窗口: 按大小排序") 836 | vim.SetAction("","左窗口: 按日期时间排序") 837 | vim.SetAction("","左窗口: 不排序") 838 | vim.SetAction("","左窗口: 反向排序") 839 | vim.SetAction("","左窗口: 打开驱动器列表") 840 | vim.SetAction("","左窗口: 焦点置于路径上") 841 | vim.SetAction("","左窗口: 展开所有文件夹") 842 | vim.SetAction("","左窗口: 只展开选中的文件夹") 843 | vim.SetAction("","窗口: 缩略图") 844 | vim.SetAction("","窗口: 自定义视图菜单") 845 | vim.SetAction("","右窗口: 显示文件备注") 846 | vim.SetAction("","右窗口: 列表") 847 | vim.SetAction("","详细信息") 848 | vim.SetAction("","右窗口: 文件夹树") 849 | vim.SetAction("","右窗口: 快速查看") 850 | vim.SetAction("","右窗口: 快速查看(不用插件)") 851 | vim.SetAction("","右窗口: 关闭快速查看窗口") 852 | vim.SetAction("","右窗口: 可执行文件") 853 | vim.SetAction("","右窗口: 所有文件") 854 | vim.SetAction("","右窗口: 上次选中的文件") 855 | vim.SetAction("","右窗口: 自定义类型") 856 | vim.SetAction("","右窗口: 按文件名排序") 857 | vim.SetAction("","右窗口: 按扩展名排序") 858 | vim.SetAction("","右窗口: 按大小排序") 859 | vim.SetAction("","右窗口: 按日期时间排序") 860 | vim.SetAction("","右窗口: 不排序") 861 | vim.SetAction("","右窗口: 反向排序") 862 | vim.SetAction("","右窗口: 打开驱动器列表") 863 | vim.SetAction("","右窗口: 焦点置于路径上") 864 | vim.SetAction("","右窗口: 展开所有文件夹") 865 | vim.SetAction("","右窗口: 只展开选中的文件夹") 866 | vim.SetAction("","右窗口: 缩略图") 867 | vim.SetAction("","右窗口: 自定义视图菜单") 868 | vim.SetAction("","查看(用查看程序)") 869 | vim.SetAction("","查看(用查看程序, 但不用插件/多媒体)") 870 | vim.SetAction("","编辑") 871 | vim.SetAction("","复制") 872 | vim.SetAction("","复制到当前窗口") 873 | vim.SetAction("","复制到另一窗口") 874 | vim.SetAction("","重命名/移动") 875 | vim.SetAction("","新建文件夹") 876 | vim.SetAction("","删除") 877 | vim.SetAction("","测试压缩包") 878 | vim.SetAction("","压缩文件") 879 | vim.SetAction("","解压文件") 880 | vim.SetAction("","重命名(Shift+F6)") 881 | vim.SetAction("","重命名当前文件") 882 | vim.SetAction("","移动(F6)") 883 | vim.SetAction("","显示属性") 884 | vim.SetAction("","创建快捷方式") 885 | vim.SetAction("","模仿按 ENTER 键") 886 | vim.SetAction("","以其他用户身份运行光标处的程序") 887 | vim.SetAction("","分割文件") 888 | vim.SetAction("","合并文件") 889 | vim.SetAction("","编码文件(MIME/UUE/XXE 格式)") 890 | vim.SetAction("","解码文件(MIME/UUE/XXE/BinHex 格式)") 891 | vim.SetAction("","创建校验文件") 892 | vim.SetAction("","验证校验和") 893 | vim.SetAction("","更改属性") 894 | vim.SetAction("","配置: 布局") 895 | vim.SetAction("","配置: 显示") 896 | vim.SetAction("","配置: 图标") 897 | vim.SetAction("","配置: 字体") 898 | vim.SetAction("","配置: 颜色") 899 | vim.SetAction("","配置: 制表符") 900 | vim.SetAction("","配置: 文件夹标签") 901 | vim.SetAction("","配置: 自定义列") 902 | vim.SetAction("","更改当前自定义列") 903 | vim.SetAction("","配置: 语言") 904 | vim.SetAction("","配置: 操作方式") 905 | vim.SetAction("","配置: 编辑/查看") 906 | vim.SetAction("","配置: 复制/删除") 907 | vim.SetAction("","配置: 刷新") 908 | vim.SetAction("","配置: 快速搜索") 909 | vim.SetAction("","配置: FTP") 910 | vim.SetAction("","配置: 插件") 911 | vim.SetAction("","配置: 缩略图") 912 | vim.SetAction("","配置: 日志文件") 913 | vim.SetAction("","配置: 隐藏文件") 914 | vim.SetAction("","配置: 压缩程序") 915 | vim.SetAction("","配置: ZIP 压缩程序") 916 | vim.SetAction("","配置: 其他/确认") 917 | vim.SetAction("","保存位置") 918 | vim.SetAction("","更改工具栏") 919 | vim.SetAction("","保存设置") 920 | vim.SetAction("","直接修改配置文件") 921 | vim.SetAction("","保存文件夹历史记录") 922 | vim.SetAction("","更改开始菜单") 923 | vim.SetAction("","映射网络驱动器") 924 | vim.SetAction("","断开网络驱动器") 925 | vim.SetAction("","共享当前文件夹") 926 | vim.SetAction("","取消文件夹共享") 927 | vim.SetAction("","显示系统共享文件夹") 928 | vim.SetAction("","显示本地文件的远程用户") 929 | vim.SetAction("","计算占用空间") 930 | vim.SetAction("","设置卷标") 931 | vim.SetAction("","版本信息") 932 | vim.SetAction("","打开命令提示符窗口") 933 | vim.SetAction("","比较文件夹") 934 | vim.SetAction("","比较文件夹(同时标出另一窗口没有的子文件夹)") 935 | vim.SetAction("","显示快捷菜单") 936 | vim.SetAction("","显示快捷菜单(内部关联)") 937 | vim.SetAction("","显示光标处文件的内部关联快捷菜单") 938 | vim.SetAction("","媒体中心遥控器播放/暂停键快捷菜单") 939 | vim.SetAction("","两边窗口同步更改文件夹") 940 | vim.SetAction("","编辑文件备注") 941 | vim.SetAction("","焦点置于左窗口") 942 | vim.SetAction("","焦点置于右窗口") 943 | vim.SetAction("","焦点置于命令行") 944 | vim.SetAction("","焦点置于工具栏") 945 | vim.SetAction("","计算所有文件夹占用的空间") 946 | vim.SetAction("","卸载所有插件") 947 | vim.SetAction("","标出新文件, 隐藏相同者") 948 | vim.SetAction("","交换左右窗口") 949 | vim.SetAction("","目标 = 来源") 950 | vim.SetAction("","刷新选中文件的缩略图") 951 | vim.SetAction("","直接电缆连接") 952 | vim.SetAction("","加载 NT 并口驱动程序") 953 | vim.SetAction("","卸载 NT 并口驱动程序") 954 | vim.SetAction("","打印文件列表") 955 | vim.SetAction("","打印文件列表(含子文件夹)") 956 | vim.SetAction("","打印文件内容") 957 | vim.SetAction("","选择一组文件") 958 | vim.SetAction("","选择一组: 文件和文件夹") 959 | vim.SetAction("","选择一组: 仅文件") 960 | vim.SetAction("","选择一组: 仅文件夹") 961 | vim.SetAction("","不选一组文件") 962 | vim.SetAction("","不选一组: 仅文件") 963 | vim.SetAction("","不选一组: 仅文件夹") 964 | vim.SetAction("","不选一组: 文件和/或文件夹(视配置而定)") 965 | vim.SetAction("","全部选择: 文件和/或文件夹(视配置而定)") 966 | vim.SetAction("","全部选择: 文件和文件夹") 967 | vim.SetAction("","全部选择: 仅文件") 968 | vim.SetAction("","全部选择: 仅文件夹") 969 | vim.SetAction("","全部取消: 文件和文件夹") 970 | vim.SetAction("","全部取消: 仅文件") 971 | vim.SetAction("","全部取消: 仅文件夹") 972 | vim.SetAction("","全部取消: 文件和/或文件夹(视配置而定)") 973 | vim.SetAction("","反向选择") 974 | vim.SetAction("","反向选择: 文件和文件夹") 975 | vim.SetAction("","反向选择: 仅文件") 976 | vim.SetAction("","反向选择: 仅文件夹") 977 | vim.SetAction("","选择扩展名相同的文件") 978 | vim.SetAction("","不选扩展名相同的文件") 979 | vim.SetAction("","选择文件名相同的文件") 980 | vim.SetAction("","不选文件名相同的文件") 981 | vim.SetAction("","选择文件名和扩展名相同的文件") 982 | vim.SetAction("","不选文件名和扩展名相同的文件") 983 | vim.SetAction("","选择同一路径下的文件(展开文件夹+搜索文件)") 984 | vim.SetAction("","不选同一路径下的文件(展开文件夹+搜索文件)") 985 | vim.SetAction("","恢复选择列表") 986 | vim.SetAction("","保存选择列表") 987 | vim.SetAction("","导出选择列表") 988 | vim.SetAction("","导出选择列表(ANSI)") 989 | vim.SetAction("","导出选择列表(Unicode)") 990 | vim.SetAction("","导出详细信息") 991 | vim.SetAction("","导出详细信息(ANSI)") 992 | vim.SetAction("","导出详细信息(Unicode)") 993 | vim.SetAction("","导入选择列表(从文件)") 994 | vim.SetAction("","导入选择列表(从剪贴板)") 995 | vim.SetAction("","设置权限(NTFS)") 996 | vim.SetAction("","审核文件(NTFS)") 997 | vim.SetAction("","获取所有权(NTFS)") 998 | vim.SetAction("","剪切选中的文件到剪贴板") 999 | vim.SetAction("","复制选中的文件到剪贴板") 1000 | vim.SetAction("","从剪贴板粘贴到当前文件夹") 1001 | vim.SetAction("","复制文件名") 1002 | vim.SetAction("","复制文件名及完整路径") 1003 | vim.SetAction("","复制文件名及网络路径") 1004 | vim.SetAction("","复制来源路径") 1005 | vim.SetAction("","复制目标路径") 1006 | vim.SetAction("","复制文件详细信息") 1007 | vim.SetAction("","复制文件详细信息及完整路径") 1008 | vim.SetAction("","复制文件详细信息及网络路径") 1009 | vim.SetAction("","FTP 连接") 1010 | vim.SetAction("","新建 FTP 连接") 1011 | vim.SetAction("","断开 FTP 连接") 1012 | vim.SetAction("","显示隐藏文件") 1013 | vim.SetAction("","中止当前 FTP 命令") 1014 | vim.SetAction("","续传") 1015 | vim.SetAction("","选择传输模式") 1016 | vim.SetAction("","添加到下载列表") 1017 | vim.SetAction("","按列表下载") 1018 | vim.SetAction("","后退") 1019 | vim.SetAction("","前进") 1020 | vim.SetAction("","文件夹历史记录") 1021 | vim.SetAction("","后退(非 FTP)") 1022 | vim.SetAction("","前进(非 FTP)") 1023 | vim.SetAction("","常用文件夹") 1024 | vim.SetAction("","转到根文件夹") 1025 | vim.SetAction("","转到上层文件夹") 1026 | vim.SetAction("","打开光标处的文件夹或压缩包") 1027 | vim.SetAction("","桌面") 1028 | vim.SetAction("","我的电脑") 1029 | vim.SetAction("","控制面板") 1030 | vim.SetAction("","字体") 1031 | vim.SetAction("","网上邻居") 1032 | vim.SetAction("","打印机") 1033 | vim.SetAction("","回收站") 1034 | vim.SetAction("","更改文件夹") 1035 | vim.SetAction("","在左窗口打开光标处的文件夹或压缩包") 1036 | vim.SetAction("","在右窗口打开光标处的文件夹或压缩包") 1037 | vim.SetAction("","编辑来源窗口的路径") 1038 | vim.SetAction("","光标移到列表中的第一个文件") 1039 | vim.SetAction("","转到下一个驱动器") 1040 | vim.SetAction("","转到上一个驱动器") 1041 | vim.SetAction("","转到下一个选中的文件") 1042 | vim.SetAction("","转到上一个选中的文件") 1043 | vim.SetAction("","转到驱动器 A") 1044 | vim.SetAction("","转到驱动器 C") 1045 | vim.SetAction("","转到驱动器 D") 1046 | vim.SetAction("","转到驱动器 E") 1047 | vim.SetAction("","可自定义其他驱动器") 1048 | vim.SetAction("","最多 26 个") 1049 | vim.SetAction("","帮助索引") 1050 | vim.SetAction("","快捷键列表") 1051 | vim.SetAction("","注册信息") 1052 | vim.SetAction("","访问 Totalcmd 网站") 1053 | vim.SetAction("","关于 Total Commander") 1054 | vim.SetAction("","退出 Total Commander") 1055 | vim.SetAction("","最小化 Total Commander") 1056 | vim.SetAction("","最大化 Total Commander") 1057 | vim.SetAction("","恢复正常大小") 1058 | vim.SetAction("","清除命令行") 1059 | vim.SetAction("","下一条命令") 1060 | vim.SetAction("","上一条命令") 1061 | vim.SetAction("","将路径复制到命令行") 1062 | vim.SetAction("","批量重命名") 1063 | vim.SetAction("","系统信息") 1064 | vim.SetAction("","后台传输管理器") 1065 | vim.SetAction("","搜索文件") 1066 | vim.SetAction("","搜索文件(单独进程)") 1067 | vim.SetAction("","同步文件夹") 1068 | vim.SetAction("","文件关联") 1069 | vim.SetAction("","定义内部关联") 1070 | vim.SetAction("","比较文件内容") 1071 | vim.SetAction("","使用内部比较程序") 1072 | vim.SetAction("","浏览内部命令") 1073 | vim.SetAction("","显示/隐藏: 工具栏") 1074 | vim.SetAction("","显示/隐藏: 驱动器按钮") 1075 | vim.SetAction("","显示/隐藏: 两个驱动器按钮栏") 1076 | vim.SetAction("","切换: 平坦/立体驱动器按钮") 1077 | vim.SetAction("","切换: 平坦/立体用户界面") 1078 | vim.SetAction("","显示/隐藏: 驱动器列表") 1079 | vim.SetAction("","显示/隐藏: 当前文件夹") 1080 | vim.SetAction("","显示/隐藏: 路径导航栏") 1081 | vim.SetAction("","显示/隐藏: 排序制表符") 1082 | vim.SetAction("","显示/隐藏: 状态栏") 1083 | vim.SetAction("","显示/隐藏: 命令行") 1084 | vim.SetAction("","显示/隐藏: 功能键按钮") 1085 | vim.SetAction("","显示文件提示") 1086 | vim.SetAction("","显示快速搜索窗口") 1087 | vim.SetAction("","开启/关闭: 长文件名显示") 1088 | vim.SetAction("","刷新来源窗口") 1089 | vim.SetAction("","仅显示选中的文件") 1090 | vim.SetAction("","开启/关闭: 隐藏或系统文件显示") 1091 | vim.SetAction("","开启/关闭: 8.3 式文件名小写显示") 1092 | vim.SetAction("","开启/关闭: 文件夹按名称排序") 1093 | vim.SetAction("","展开所有文件夹") 1094 | vim.SetAction("","只展开选中的文件夹") 1095 | vim.SetAction("","窗口分隔栏位于 50%") 1096 | vim.SetAction("","窗口分隔栏位于 100% TC 8.0+") 1097 | vim.SetAction("","显示/隐藏: 文件夹标签") 1098 | vim.SetAction("","显示/隐藏: XP 主题背景") 1099 | vim.SetAction("","开启/关闭: 叠置图标显示") 1100 | vim.SetAction("","显示/隐藏: 文件夹历史记录和常用文件夹按钮") 1101 | vim.SetAction("","启用/禁用: 文件夹自动刷新") 1102 | vim.SetAction("","启用/禁用: 自定义隐藏文件") 1103 | vim.SetAction("","开启/关闭: 32 位 system32 目录重定向(64 位 Windows)") 1104 | vim.SetAction("","关闭独立文件夹树面板") 1105 | vim.SetAction("","一个独立文件夹树面板") 1106 | vim.SetAction("","两个独立文件夹树面板") 1107 | vim.SetAction("","切换独立文件夹树面板状态") 1108 | vim.SetAction("","开启/关闭: 一个独立文件夹树面板") 1109 | vim.SetAction("","开启/关闭: 两个独立文件夹树面板") 1110 | vim.SetAction("","用户菜单 1") 1111 | vim.SetAction("","用户菜单 2") 1112 | vim.SetAction("","用户菜单 3") 1113 | vim.SetAction("","用户菜单 4") 1114 | vim.SetAction("","用户菜单 5") 1115 | vim.SetAction("","用户菜单 6") 1116 | vim.SetAction("","用户菜单 7") 1117 | vim.SetAction("","用户菜单 8") 1118 | vim.SetAction("","用户菜单 9") 1119 | vim.SetAction("","可定义其他用户菜单") 1120 | vim.SetAction("","新建标签") 1121 | vim.SetAction("","新建标签(在后台)") 1122 | vim.SetAction("","新建标签(并打开光标处的文件夹)") 1123 | vim.SetAction("","新建标签(在另一窗口打开文件夹)") 1124 | vim.SetAction("","下一个标签(Ctrl+Tab)") 1125 | vim.SetAction("","上一个标签(Ctrl+Shift+Tab)") 1126 | vim.SetAction("","关闭当前标签") 1127 | vim.SetAction("","关闭所有标签") 1128 | vim.SetAction("","显示标签菜单") 1129 | vim.SetAction("","锁定/解锁当前标签") 1130 | vim.SetAction("","锁定/解锁当前标签(可更改文件夹)") 1131 | vim.SetAction("","交换左右窗口及其标签") 1132 | vim.SetAction("","转到锁定标签的根文件夹") 1133 | vim.SetAction("","来源窗口: 激活标签 1") 1134 | vim.SetAction("","来源窗口: 激活标签 2") 1135 | vim.SetAction("","来源窗口: 激活标签 3") 1136 | vim.SetAction("","来源窗口: 激活标签 4") 1137 | vim.SetAction("","来源窗口: 激活标签 5") 1138 | vim.SetAction("","来源窗口: 激活标签 6") 1139 | vim.SetAction("","来源窗口: 激活标签 7") 1140 | vim.SetAction("","来源窗口: 激活标签 8") 1141 | vim.SetAction("","来源窗口: 激活标签 9") 1142 | vim.SetAction("","来源窗口: 激活标签 10") 1143 | vim.SetAction("","目标窗口: 激活标签 1") 1144 | vim.SetAction("","目标窗口: 激活标签 2") 1145 | vim.SetAction("","目标窗口: 激活标签 3") 1146 | vim.SetAction("","目标窗口: 激活标签 4") 1147 | vim.SetAction("","目标窗口: 激活标签 5") 1148 | vim.SetAction("","目标窗口: 激活标签 6") 1149 | vim.SetAction("","目标窗口: 激活标签 7") 1150 | vim.SetAction("","目标窗口: 激活标签 8") 1151 | vim.SetAction("","目标窗口: 激活标签 9") 1152 | vim.SetAction("","目标窗口: 激活标签 10") 1153 | vim.SetAction("","左窗口: 激活标签 1") 1154 | vim.SetAction("","左窗口: 激活标签 2") 1155 | vim.SetAction("","左窗口: 激活标签 3") 1156 | vim.SetAction("","左窗口: 激活标签 4") 1157 | vim.SetAction("","左窗口: 激活标签 5") 1158 | vim.SetAction("","左窗口: 激活标签 6") 1159 | vim.SetAction("","左窗口: 激活标签 7") 1160 | vim.SetAction("","左窗口: 激活标签 8") 1161 | vim.SetAction("","左窗口: 激活标签 9") 1162 | vim.SetAction("","左窗口: 激活标签 10") 1163 | vim.SetAction("","右窗口: 激活标签 1") 1164 | vim.SetAction("","右窗口: 激活标签 2") 1165 | vim.SetAction("","右窗口: 激活标签 3") 1166 | vim.SetAction("","右窗口: 激活标签 4") 1167 | vim.SetAction("","右窗口: 激活标签 5") 1168 | vim.SetAction("","右窗口: 激活标签 6") 1169 | vim.SetAction("","右窗口: 激活标签 7") 1170 | vim.SetAction("","右窗口: 激活标签 8") 1171 | vim.SetAction("","右窗口: 激活标签 9") 1172 | vim.SetAction("","右窗口: 激活标签 10") 1173 | vim.SetAction("","来源窗口: 按第 1 列排序") 1174 | vim.SetAction("","来源窗口: 按第 2 列排序") 1175 | vim.SetAction("","来源窗口: 按第 3 列排序") 1176 | vim.SetAction("","来源窗口: 按第 4 列排序") 1177 | vim.SetAction("","来源窗口: 按第 5 列排序") 1178 | vim.SetAction("","来源窗口: 按第 6 列排序") 1179 | vim.SetAction("","来源窗口: 按第 7 列排序") 1180 | vim.SetAction("","来源窗口: 按第 8 列排序") 1181 | vim.SetAction("","来源窗口: 按第 9 列排序") 1182 | vim.SetAction("","来源窗口: 按第 10 列排序") 1183 | vim.SetAction("","目标窗口: 按第 1 列排序") 1184 | vim.SetAction("","目标窗口: 按第 2 列排序") 1185 | vim.SetAction("","目标窗口: 按第 3 列排序") 1186 | vim.SetAction("","目标窗口: 按第 4 列排序") 1187 | vim.SetAction("","目标窗口: 按第 5 列排序") 1188 | vim.SetAction("","目标窗口: 按第 6 列排序") 1189 | vim.SetAction("","目标窗口: 按第 7 列排序") 1190 | vim.SetAction("","目标窗口: 按第 8 列排序") 1191 | vim.SetAction("","目标窗口: 按第 9 列排序") 1192 | vim.SetAction("","目标窗口: 按第 10 列排序") 1193 | vim.SetAction("","左窗口: 按第 1 列排序") 1194 | vim.SetAction("","左窗口: 按第 2 列排序") 1195 | vim.SetAction("","左窗口: 按第 3 列排序") 1196 | vim.SetAction("","左窗口: 按第 4 列排序") 1197 | vim.SetAction("","左窗口: 按第 5 列排序") 1198 | vim.SetAction("","左窗口: 按第 6 列排序") 1199 | vim.SetAction("","左窗口: 按第 7 列排序") 1200 | vim.SetAction("","左窗口: 按第 8 列排序") 1201 | vim.SetAction("","左窗口: 按第 9 列排序") 1202 | vim.SetAction("","左窗口: 按第 10 列排序") 1203 | vim.SetAction("","右窗口: 按第 1 列排序") 1204 | vim.SetAction("","右窗口: 按第 2 列排序") 1205 | vim.SetAction("","右窗口: 按第 3 列排序") 1206 | vim.SetAction("","右窗口: 按第 4 列排序") 1207 | vim.SetAction("","右窗口: 按第 5 列排序") 1208 | vim.SetAction("","右窗口: 按第 6 列排序") 1209 | vim.SetAction("","右窗口: 按第 7 列排序") 1210 | vim.SetAction("","右窗口: 按第 8 列排序") 1211 | vim.SetAction("","右窗口: 按第 9 列排序") 1212 | vim.SetAction("","右窗口: 按第 10 列排序") 1213 | vim.SetAction("","来源窗口: 自定义列视图 1") 1214 | vim.SetAction("","来源窗口: 自定义列视图 2") 1215 | vim.SetAction("","来源窗口: 自定义列视图 3") 1216 | vim.SetAction("","来源窗口: 自定义列视图 4") 1217 | vim.SetAction("","来源窗口: 自定义列视图 5") 1218 | vim.SetAction("","来源窗口: 自定义列视图 6") 1219 | vim.SetAction("","来源窗口: 自定义列视图 7") 1220 | vim.SetAction("","来源窗口: 自定义列视图 8") 1221 | vim.SetAction("","来源窗口: 自定义列视图 9") 1222 | vim.SetAction("","来源窗口: 自定义列视图 10") 1223 | vim.SetAction("","左窗口: 自定义列视图 1") 1224 | vim.SetAction("","左窗口: 自定义列视图 2") 1225 | vim.SetAction("","左窗口: 自定义列视图 3") 1226 | vim.SetAction("","左窗口: 自定义列视图 4") 1227 | vim.SetAction("","左窗口: 自定义列视图 5") 1228 | vim.SetAction("","左窗口: 自定义列视图 6") 1229 | vim.SetAction("","左窗口: 自定义列视图 7") 1230 | vim.SetAction("","左窗口: 自定义列视图 8") 1231 | vim.SetAction("","左窗口: 自定义列视图 9") 1232 | vim.SetAction("","左窗口: 自定义列视图 10") 1233 | vim.SetAction("","右窗口: 自定义列视图 1") 1234 | vim.SetAction("","右窗口: 自定义列视图 2") 1235 | vim.SetAction("","右窗口: 自定义列视图 3") 1236 | vim.SetAction("","右窗口: 自定义列视图 4") 1237 | vim.SetAction("","右窗口: 自定义列视图 5") 1238 | vim.SetAction("","右窗口: 自定义列视图 6") 1239 | vim.SetAction("","右窗口: 自定义列视图 7") 1240 | vim.SetAction("","右窗口: 自定义列视图 8") 1241 | vim.SetAction("","右窗口: 自定义列视图 9") 1242 | vim.SetAction("","右窗口: 自定义列视图 10") 1243 | vim.SetAction("","来源窗口: 下一个自定义视图") 1244 | vim.SetAction("","来源窗口: 上一个自定义视图") 1245 | vim.SetAction("","目标窗口: 下一个自定义视图") 1246 | vim.SetAction("","目标窗口: 上一个自定义视图") 1247 | vim.SetAction("","左窗口: 下一个自定义视图") 1248 | vim.SetAction("","左窗口: 上一个自定义视图") 1249 | vim.SetAction("","右窗口: 下一个自定义视图") 1250 | vim.SetAction("","右窗口: 上一个自定义视图") 1251 | vim.SetAction("","所有文件都按需加载备注") 1252 | vim.SetAction("","仅选中的文件按需加载备注") 1253 | vim.SetAction("","停止后台加载备注") 1254 | return 1255 | SendPos(Number) 1256 | { 1257 | Global TC_SendPos := Number 1258 | PostMessage 1075, %Number%, 0, , AHK_CLASS TTOTAL_CMD 1259 | } 1260 | ;: >>来源窗口: 显示文件备注{{{2 1261 | : 1262 | SendPos(300) 1263 | Return 1264 | ;: >>来源窗口: 列表{{{2 1265 | : 1266 | SendPos(301) 1267 | Return 1268 | ;: >>来源窗口: 详细信息{{{2 1269 | : 1270 | SendPos(302) 1271 | Return 1272 | ;: >>来源窗口: 文件夹树{{{2 1273 | : 1274 | SendPos(303) 1275 | ;: >>来源窗口: 快速查看{{{2 1276 | : 1277 | SendPos(304) 1278 | Return 1279 | ;: >>纵向排列{{{2 1280 | : 1281 | SendPos(305) 1282 | Return 1283 | ;: >>来源窗口: 快速查看(不用插件){{{2 1284 | : 1285 | SendPos(306) 1286 | Return 1287 | ;: >>来源窗口: 关闭快速查看窗口{{{2 1288 | : 1289 | SendPos(307) 1290 | Return 1291 | ;: >>来源窗口: 可执行文件{{{2 1292 | : 1293 | SendPos(311) 1294 | Return 1295 | ;: >>来源窗口: 所有文件{{{2 1296 | : 1297 | SendPos(312) 1298 | Return 1299 | ;: >>来源窗口: 上次选中的文件{{{2 1300 | : 1301 | SendPos(313) 1302 | Return 1303 | ;: >>来源窗口: 自定义类型{{{2 1304 | : 1305 | SendPos(314) 1306 | Return 1307 | ;: >>来源窗口: 按文件名排序{{{2 1308 | : 1309 | SendPos(321) 1310 | Return 1311 | ;: >>来源窗口: 按扩展名排序{{{2 1312 | : 1313 | SendPos(322) 1314 | Return 1315 | ;: >>来源窗口: 按大小排序{{{2 1316 | : 1317 | SendPos(323) 1318 | Return 1319 | ;: >>来源窗口: 按日期时间排序{{{2 1320 | : 1321 | SendPos(324) 1322 | Return 1323 | ;: >>来源窗口: 不排序{{{2 1324 | : 1325 | SendPos(325) 1326 | Return 1327 | ;: >>来源窗口: 反向排序{{{2 1328 | : 1329 | SendPos(330) 1330 | Return 1331 | ;: >>来源窗口: 打开驱动器列表{{{2 1332 | : 1333 | SendPos(331) 1334 | Return 1335 | ;: >>来源窗口: 缩略图{{{2 1336 | : 1337 | SendPos(269 ) 1338 | Return 1339 | ;: >>来源窗口: 自定义视图菜单{{{2 1340 | : 1341 | SendPos(270) 1342 | Return 1343 | ;: >>来源窗口: 焦点置于路径上{{{2 1344 | : 1345 | SendPos(332) 1346 | Return 1347 | ;左窗口 ========================================= 1348 | Return 1349 | ;: >>左窗口: 显示文件备注{{{2 1350 | : 1351 | SendPos(100) 1352 | Return 1353 | ;: >>左窗口: 列表{{{2 1354 | : 1355 | SendPos(101) 1356 | Return 1357 | ;: >>左窗口: 详细信息{{{2 1358 | : 1359 | SendPos(102) 1360 | Return 1361 | ;: >>左窗口: 文件夹树{{{2 1362 | : 1363 | SendPos(103) 1364 | Return 1365 | ;: >>左窗口: 快速查看{{{2 1366 | : 1367 | SendPos(104) 1368 | Return 1369 | ;: >>左窗口: 快速查看(不用插件){{{2 1370 | : 1371 | SendPos(106) 1372 | Return 1373 | ;: >>左窗口: 关闭快速查看窗口{{{2 1374 | : 1375 | SendPos(107) 1376 | Return 1377 | ;: >>左窗口: 可执行文件{{{2 1378 | : 1379 | SendPos(111) 1380 | Return 1381 | ;: >> 左窗口: 所有文件{{{2 1382 | : 1383 | SendPos(112) 1384 | Return 1385 | ;: >>左窗口: 上次选中的文件{{{2 1386 | : 1387 | SendPos(113) 1388 | Return 1389 | ;: >>左窗口: 自定义类型{{{2 1390 | : 1391 | SendPos(114) 1392 | Return 1393 | ;: >>左窗口: 按文件名排序{{{2 1394 | : 1395 | SendPos(121) 1396 | Return 1397 | ;: >>左窗口: 按扩展名排序{{{2 1398 | : 1399 | SendPos(122) 1400 | Return 1401 | ;: >>左窗口: 按大小排序{{{2 1402 | : 1403 | SendPos(123) 1404 | Return 1405 | ;: >>左窗口: 按日期时间排序{{{2 1406 | : 1407 | SendPos(124) 1408 | Return 1409 | ;: >>左窗口: 不排序{{{2 1410 | : 1411 | SendPos(125) 1412 | Return 1413 | ;: >>左窗口: 反向排序{{{2 1414 | : 1415 | SendPos(130) 1416 | Return 1417 | ;: >>左窗口: 打开驱动器列表{{{2 1418 | : 1419 | SendPos(131) 1420 | Return 1421 | ;: >>左窗口: 焦点置于路径上{{{2 1422 | : 1423 | SendPos(132) 1424 | Return 1425 | ;: >>左窗口: 展开所有文件夹{{{2 1426 | : 1427 | SendPos(203) 1428 | Return 1429 | ;: >> 左窗口: 只展开选中的文件夹{{{2 1430 | : 1431 | SendPos(204) 1432 | Return 1433 | ;: >>窗口: 缩略图{{{2 1434 | : 1435 | SendPos(69) 1436 | Return 1437 | ;: >> 窗口: 自定义视图菜单{{{2 1438 | : 1439 | SendPos(70) 1440 | Return 1441 | ;右窗口 ========================================= 1442 | Return 1443 | ;: >>右窗口: 显示文件备注{{{2 1444 | : 1445 | SendPos(200) 1446 | Return 1447 | ;: >>右窗口: 列表{{{2 1448 | : 1449 | SendPos(201) 1450 | Return 1451 | ;: >> 详细信息{{{2 1452 | : 1453 | SendPos(202) 1454 | Return 1455 | ;: >> 右窗口: 文件夹树{{{2 1456 | : 1457 | SendPos(203) 1458 | Return 1459 | ;: >> 右窗口: 快速查看{{{2 1460 | : 1461 | SendPos(204) 1462 | Return 1463 | ;: >> 右窗口: 快速查看(不用插件){{{2 1464 | : 1465 | SendPos(206) 1466 | Return 1467 | ;: >> 右窗口: 关闭快速查看窗口{{{2 1468 | : 1469 | SendPos(207) 1470 | Return 1471 | ;: >> 右窗口: 可执行文件{{{2 1472 | : 1473 | SendPos(211) 1474 | Return 1475 | ;: >> 右窗口: 所有文件{{{2 1476 | : 1477 | SendPos(212) 1478 | Return 1479 | ;: >> 右窗口: 上次选中的文件{{{2 1480 | : 1481 | SendPos(213) 1482 | Return 1483 | ;: >> 右窗口: 自定义类型{{{2 1484 | : 1485 | SendPos(214) 1486 | Return 1487 | ;: >> 右窗口: 按文件名排序{{{2 1488 | : 1489 | SendPos(221) 1490 | Return 1491 | ;: >> 右窗口: 按扩展名排序{{{2 1492 | : 1493 | SendPos(222) 1494 | Return 1495 | ;: >> 右窗口: 按大小排序{{{2 1496 | : 1497 | SendPos(223) 1498 | Return 1499 | ;: >> 右窗口: 按日期时间排序{{{2 1500 | : 1501 | SendPos(224) 1502 | Return 1503 | ;: >> 右窗口: 不排序{{{2 1504 | : 1505 | SendPos(225) 1506 | Return 1507 | ;: >> 右窗口: 反向排序{{{2 1508 | : 1509 | SendPos(230) 1510 | Return 1511 | ;: >> 右窗口: 打开驱动器列表{{{2 1512 | : 1513 | SendPos(231) 1514 | Return 1515 | ;: >> 右窗口: 焦点置于路径上{{{2 1516 | : 1517 | SendPos(232) 1518 | Return 1519 | ;: >>右窗口: 展开所有文件夹{{{2 1520 | : 1521 | SendPos(2035) 1522 | Return 1523 | ;: >>右窗口: 只展开选中的文件夹{{{2 1524 | : 1525 | SendPos(2048) 1526 | Return 1527 | ;: >> 右窗口: 缩略图{{{2 1528 | : 1529 | SendPos(169) 1530 | Return 1531 | ;: >> 右窗口: 自定义视图菜单{{{2 1532 | : 1533 | SendPos(170) 1534 | Return 1535 | ;文件操作 ========================================= 1536 | Return 1537 | ;: >> 查看(用查看程序){{{2 1538 | : 1539 | SendPos(903) 1540 | Return 1541 | ;: >>查看(用查看程序, 但不用插件/多媒体){{{2 1542 | : 1543 | SendPos(1006) 1544 | Return 1545 | ;: >> 编辑{{{2 1546 | : 1547 | SendPos(904) 1548 | Return 1549 | ;: >>复制{{{2 1550 | : 1551 | SendPos(905) 1552 | Return 1553 | ;: >>复制到当前窗口{{{2 1554 | : 1555 | SendPos(3100) 1556 | Return 1557 | ;: >>复制到另一窗口{{{2 1558 | : 1559 | SendPos(3101) 1560 | Return 1561 | ;: >>重命名/移动{{{2 1562 | : 1563 | SendPos(906) 1564 | Return 1565 | ;: >>新建文件夹{{{2 1566 | : 1567 | SendPos(907) 1568 | Return 1569 | ;: >>删除{{{2 1570 | : 1571 | SendPos(908) 1572 | Return 1573 | ;: >>测试压缩包{{{2 1574 | : 1575 | SendPos(518) 1576 | Return 1577 | ;: >>压缩文件{{{2 1578 | : 1579 | SendPos(508) 1580 | Return 1581 | ;: >>解压文件{{{2 1582 | : 1583 | SendPos(509) 1584 | Return 1585 | ;: >>重命名(Shift+F6){{{2 1586 | : 1587 | SendPos(1002) 1588 | Return 1589 | ;: >>重命名当前文件{{{2 1590 | : 1591 | SendPos(1007) 1592 | Return 1593 | ;: >>移动(F6){{{2 1594 | : 1595 | SendPos(1005) 1596 | Return 1597 | ;: >>显示属性{{{2 1598 | : 1599 | SendPos(1003) 1600 | Return 1601 | ;: >>创建快捷方式{{{2 1602 | : 1603 | SendPos(1004) 1604 | Return 1605 | ;: >>模仿按 ENTER 键{{{2 1606 | : 1607 | SendPos(1001) 1608 | Return 1609 | ;: >>以其他用户身份运行光标处的程序{{{2 1610 | : 1611 | SendPos(2800) 1612 | Return 1613 | ;: >>分割文件{{{2 1614 | : 1615 | SendPos(560) 1616 | Return 1617 | ;: >>合并文件{{{2 1618 | : 1619 | SendPos(561) 1620 | Return 1621 | ;: >>编码文件(MIME/UUE/XXE 格式){{{2 1622 | : 1623 | SendPos(562) 1624 | Return 1625 | ;: >>解码文件(MIME/UUE/XXE/BinHex 格式){{{2 1626 | : 1627 | SendPos(563) 1628 | Return 1629 | ;: >>创建校验文件{{{2 1630 | : 1631 | SendPos(564) 1632 | Return 1633 | ;: >>验证校验和{{{2 1634 | : 1635 | SendPos(565) 1636 | Return 1637 | ;: >>更改属性{{{2 1638 | : 1639 | SendPos(502) 1640 | Return 1641 | ;配置 ========================================= 1642 | Return 1643 | ;: >>配置: 布局{{{2 1644 | : 1645 | SendPos(490) 1646 | Return 1647 | ;: >>配置: 显示{{{2 1648 | : 1649 | SendPos(486) 1650 | Return 1651 | ;: >>配置: 图标{{{2 1652 | : 1653 | SendPos(477) 1654 | Return 1655 | ;: >>配置: 字体{{{2 1656 | : 1657 | SendPos(492) 1658 | Return 1659 | ;: >>配置: 颜色{{{2 1660 | : 1661 | SendPos(494) 1662 | Return 1663 | ;: >>配置: 制表符{{{2 1664 | : 1665 | SendPos(497) 1666 | Return 1667 | ;: >>配置: 文件夹标签{{{2 1668 | : 1669 | SendPos(488) 1670 | Return 1671 | ;: >>配置: 自定义列{{{2 1672 | : 1673 | SendPos(483) 1674 | Return 1675 | ;: >>更改当前自定义列{{{2 1676 | : 1677 | SendPos(2920) 1678 | Return 1679 | ;: >>配置: 语言{{{2 1680 | : 1681 | SendPos(499) 1682 | Return 1683 | ;: >>配置: 操作方式{{{2 1684 | : 1685 | SendPos(516) 1686 | Return 1687 | ;: >>配置: 编辑/查看{{{2 1688 | : 1689 | SendPos(496) 1690 | Return 1691 | ;: >>配置: 复制/删除{{{2 1692 | : 1693 | SendPos(487) 1694 | Return 1695 | ;: >>配置: 刷新{{{2 1696 | : 1697 | SendPos(478) 1698 | Return 1699 | ;: >>配置: 快速搜索{{{2 1700 | : 1701 | SendPos(479) 1702 | Return 1703 | ;: >>配置: FTP{{{2 1704 | : 1705 | SendPos(489) 1706 | Return 1707 | ;: >>配置: 插件{{{2 1708 | : 1709 | SendPos(484) 1710 | Return 1711 | ;: >>配置: 缩略图{{{2 1712 | : 1713 | SendPos(482) 1714 | Return 1715 | ;: >>配置: 日志文件{{{2 1716 | : 1717 | SendPos(481) 1718 | Return 1719 | ;: >>配置: 隐藏文件{{{2 1720 | : 1721 | SendPos(480) 1722 | Return 1723 | ;: >>配置: 压缩程序{{{2 1724 | : 1725 | SendPos(491) 1726 | Return 1727 | ;: >>配置: ZIP 压缩程序{{{2 1728 | : 1729 | SendPos(485) 1730 | Return 1731 | ;: >>配置: 其他/确认{{{2 1732 | : 1733 | SendPos(495) 1734 | Return 1735 | ;: >>保存位置{{{2 1736 | : 1737 | SendPos(493) 1738 | Return 1739 | ;: >>更改工具栏{{{2 1740 | : 1741 | SendPos(498) 1742 | Return 1743 | ;: >>保存设置{{{2 1744 | : 1745 | SendPos(580) 1746 | Return 1747 | ;: >>直接修改配置文件{{{2 1748 | : 1749 | SendPos(581) 1750 | Return 1751 | ;: >>保存文件夹历史记录{{{2 1752 | : 1753 | SendPos(582) 1754 | Return 1755 | ;: >>更改开始菜单{{{2 1756 | : 1757 | SendPos(700) 1758 | Return 1759 | ;网络 ========================================= 1760 | Return 1761 | ;: >>映射网络驱动器{{{2 1762 | : 1763 | SendPos(512) 1764 | Return 1765 | ;: >>断开网络驱动器{{{2 1766 | : 1767 | SendPos(513) 1768 | Return 1769 | ;: >>共享当前文件夹{{{2 1770 | : 1771 | SendPos(514) 1772 | Return 1773 | ;: >>取消文件夹共享{{{2 1774 | : 1775 | SendPos(515) 1776 | Return 1777 | ;: >>显示系统共享文件夹{{{2 1778 | : 1779 | SendPos(2204) 1780 | Return 1781 | ;: >>显示本地文件的远程用户{{{2 1782 | : 1783 | SendPos(2203) 1784 | Return 1785 | ;其他 ========================================= 1786 | Return 1787 | ;: >>计算占用空间{{{2 1788 | : 1789 | SendPos(503) 1790 | Return 1791 | ;: >>设置卷标{{{2 1792 | : 1793 | SendPos(505) 1794 | Return 1795 | ;: >>版本信息{{{2 1796 | : 1797 | SendPos(510) 1798 | Return 1799 | ;: >>打开命令提示符窗口{{{2 1800 | : 1801 | SendPos(511) 1802 | Return 1803 | ;: >>比较文件夹{{{2 1804 | : 1805 | SendPos(533) 1806 | Return 1807 | ;: >>比较文件夹(同时标出另一窗口没有的子文件夹){{{2 1808 | : 1809 | SendPos(536) 1810 | Return 1811 | ;: >>显示快捷菜单{{{2 1812 | : 1813 | SendPos(2500) 1814 | Return 1815 | ;: >>显示快捷菜单(内部关联){{{2 1816 | : 1817 | SendPos(2927) 1818 | Return 1819 | ;: >>显示光标处文件的内部关联快捷菜单{{{2 1820 | : 1821 | SendPos(2928) 1822 | Return 1823 | ;: >>媒体中心遥控器播放/暂停键快捷菜单{{{2 1824 | : 1825 | SendPos(2930) 1826 | Return 1827 | ;: >>两边窗口同步更改文件夹{{{2 1828 | : 1829 | SendPos(2600) 1830 | Return 1831 | ;: >>编辑文件备注{{{2 1832 | : 1833 | SendPos(2700) 1834 | Return 1835 | ;: >>焦点置于左窗口{{{2 1836 | : 1837 | SendPos(4001) 1838 | Return 1839 | ;: >>焦点置于右窗口{{{2 1840 | : 1841 | SendPos(4002) 1842 | Return 1843 | ;: >>焦点置于命令行{{{2 1844 | : 1845 | SendPos(4003) 1846 | Return 1847 | ;: >>焦点置于工具栏{{{2 1848 | : 1849 | SendPos(4004) 1850 | Return 1851 | ;: >>计算所有文件夹占用的空间{{{2 1852 | : 1853 | SendPos(2014) 1854 | Return 1855 | ;: >>卸载所有插件{{{2 1856 | : 1857 | SendPos(2913) 1858 | Return 1859 | ;: >>标出新文件, 隐藏相同者{{{2 1860 | : 1861 | SendPos(534) 1862 | Return 1863 | ;: >>交换左右窗口{{{2 1864 | : 1865 | SendPos(531) 1866 | Return 1867 | ;: >>目标 = 来源{{{2 1868 | : 1869 | SendPos(532) 1870 | Return 1871 | ;: >>刷新选中文件的缩略图{{{2 1872 | : 1873 | SendPos(2918) 1874 | Return 1875 | ;并口 ========================================= 1876 | Return 1877 | ;: >>直接电缆连接{{{2 1878 | : 1879 | SendPos(2300) 1880 | Return 1881 | ;: >>加载 NT 并口驱动程序{{{2 1882 | : 1883 | SendPos(2301) 1884 | Return 1885 | ;: >>卸载 NT 并口驱动程序{{{2 1886 | : 1887 | SendPos(2302) 1888 | Return 1889 | ;打印 ========================================= 1890 | Return 1891 | ;: >>打印文件列表{{{2 1892 | : 1893 | SendPos(2027) 1894 | Return 1895 | ;: >>打印文件列表(含子文件夹){{{2 1896 | : 1897 | SendPos(2028) 1898 | Return 1899 | ;: >>打印文件内容{{{2 1900 | : 1901 | SendPos(504) 1902 | Return 1903 | ;选择 ========================================= 1904 | Return 1905 | ;: >>选择一组文件{{{2 1906 | : 1907 | SendPos(521) 1908 | Return 1909 | ;: >>选择一组: 文件和文件夹{{{2 1910 | : 1911 | SendPos(3311) 1912 | Return 1913 | ;: >>选择一组: 仅文件{{{2 1914 | : 1915 | SendPos(3312) 1916 | Return 1917 | ;: >>选择一组: 仅文件夹{{{2 1918 | : 1919 | SendPos(3313) 1920 | Return 1921 | ;: >>不选一组文件{{{2 1922 | : 1923 | SendPos(522) 1924 | Return 1925 | ;: >>不选一组: 仅文件{{{2 1926 | : 1927 | SendPos(3314) 1928 | Return 1929 | ;: >>不选一组: 仅文件夹{{{2 1930 | : 1931 | SendPos(3315) 1932 | Return 1933 | ;: >>不选一组: 文件和/或文件夹(视配置而定){{{2 1934 | : 1935 | SendPos(3316) 1936 | Return 1937 | ;: >>全部选择: 文件和/或文件夹(视配置而定){{{2 1938 | : 1939 | SendPos(523) 1940 | Return 1941 | ;: >>全部选择: 文件和文件夹{{{2 1942 | : 1943 | SendPos(3301) 1944 | Return 1945 | ;: >>全部选择: 仅文件{{{2 1946 | : 1947 | SendPos(3302) 1948 | Return 1949 | ;: >>全部选择: 仅文件夹{{{2 1950 | : 1951 | SendPos(3303) 1952 | Return 1953 | ;: >>全部取消: 文件和文件夹{{{2 1954 | : 1955 | SendPos(524) 1956 | Return 1957 | ;: >>全部取消: 仅文件{{{2 1958 | : 1959 | SendPos(3304) 1960 | Return 1961 | ;: >>全部取消: 仅文件夹{{{2 1962 | : 1963 | SendPos(3305) 1964 | Return 1965 | ;: >>全部取消: 文件和/或文件夹(视配置而定){{{2 1966 | : 1967 | SendPos(3306) 1968 | Return 1969 | ;: >>反向选择{{{2 1970 | : 1971 | SendPos(525) 1972 | Return 1973 | ;: >>反向选择: 文件和文件夹{{{2 1974 | : 1975 | SendPos(3321) 1976 | Return 1977 | ;: >>反向选择: 仅文件{{{2 1978 | : 1979 | SendPos(3322) 1980 | Return 1981 | ;: >>反向选择: 仅文件夹{{{2 1982 | : 1983 | SendPos(3323) 1984 | Return 1985 | ;: >>选择扩展名相同的文件{{{2 1986 | : 1987 | SendPos(527) 1988 | Return 1989 | ;: >>不选扩展名相同的文件{{{2 1990 | : 1991 | SendPos(528) 1992 | Return 1993 | ;: >>选择文件名相同的文件{{{2 1994 | : 1995 | SendPos(541) 1996 | Return 1997 | ;: >>不选文件名相同的文件{{{2 1998 | : 1999 | SendPos(542) 2000 | Return 2001 | ;: >>选择文件名和扩展名相同的文件{{{2 2002 | : 2003 | SendPos(543) 2004 | Return 2005 | ;: >>不选文件名和扩展名相同的文件{{{2 2006 | : 2007 | SendPos(544) 2008 | Return 2009 | ;: >>选择同一路径下的文件(展开文件夹+搜索文件){{{2 2010 | : 2011 | SendPos(537) 2012 | Return 2013 | ;: >>不选同一路径下的文件(展开文件夹+搜索文件){{{2 2014 | : 2015 | SendPos(538) 2016 | Return 2017 | ;: >>恢复选择列表{{{2 2018 | : 2019 | SendPos(529) 2020 | Return 2021 | ;: >>保存选择列表{{{2 2022 | : 2023 | SendPos(530) 2024 | Return 2025 | ;: >>导出选择列表{{{2 2026 | : 2027 | SendPos(2031) 2028 | Return 2029 | ;: >>导出选择列表(ANSI){{{2 2030 | : 2031 | SendPos(2041) 2032 | Return 2033 | ;: >>导出选择列表(Unicode){{{2 2034 | : 2035 | SendPos(2042) 2036 | Return 2037 | ;: >>导出详细信息{{{2 2038 | : 2039 | SendPos(2039) 2040 | Return 2041 | ;: >>导出详细信息(ANSI){{{2 2042 | : 2043 | SendPos(2043) 2044 | Return 2045 | ;: >>导出详细信息(Unicode){{{2 2046 | : 2047 | SendPos(2044) 2048 | Return 2049 | ;: >>导入选择列表(从文件){{{2 2050 | : 2051 | SendPos(2032) 2052 | Return 2053 | ;: >>导入选择列表(从剪贴板){{{2 2054 | : 2055 | SendPos(2033) 2056 | Return 2057 | ;安全 ========================================= 2058 | Return 2059 | ;: >>设置权限(NTFS){{{2 2060 | : 2061 | SendPos(2200) 2062 | Return 2063 | ;: >>审核文件(NTFS){{{2 2064 | : 2065 | SendPos(2201) 2066 | Return 2067 | ;: >>获取所有权(NTFS){{{2 2068 | : 2069 | SendPos(2202) 2070 | Return 2071 | ;剪贴板 ========================================= 2072 | Return 2073 | ;: >>剪切选中的文件到剪贴板{{{2 2074 | : 2075 | SendPos(2007) 2076 | Return 2077 | ;: >>复制选中的文件到剪贴板{{{2 2078 | : 2079 | SendPos(2008) 2080 | Return 2081 | ;: >>从剪贴板粘贴到当前文件夹{{{2 2082 | : 2083 | SendPos(2009) 2084 | Return 2085 | ;: >>复制文件名{{{2 2086 | : 2087 | SendPos(2017) 2088 | Return 2089 | ;: >>复制文件名及完整路径{{{2 2090 | : 2091 | SendPos(2018) 2092 | Return 2093 | ;: >>复制文件名及网络路径{{{2 2094 | : 2095 | SendPos(2021) 2096 | Return 2097 | ;: >>复制来源路径{{{2 2098 | : 2099 | SendPos(2029) 2100 | Return 2101 | ;: >>复制目标路径{{{2 2102 | : 2103 | SendPos(2030) 2104 | Return 2105 | ;: >>复制文件详细信息{{{2 2106 | : 2107 | SendPos(2036) 2108 | Return 2109 | ;: >>复制文件详细信息及完整路径{{{2 2110 | : 2111 | SendPos(2037) 2112 | Return 2113 | ;: >>复制文件详细信息及网络路径{{{2 2114 | : 2115 | SendPos(2038) 2116 | Return 2117 | ;FTP ========================================= 2118 | Return 2119 | ;: >>FTP 连接{{{2 2120 | : 2121 | SendPos(550) 2122 | Return 2123 | ;: >>新建 FTP 连接{{{2 2124 | : 2125 | SendPos(551) 2126 | Return 2127 | ;: >>断开 FTP 连接{{{2 2128 | : 2129 | SendPos(552) 2130 | Return 2131 | ;: >>显示隐藏文件{{{2 2132 | : 2133 | SendPos(553) 2134 | Return 2135 | ;: >>中止当前 FTP 命令{{{2 2136 | : 2137 | SendPos(554) 2138 | Return 2139 | ;: >>续传{{{2 2140 | : 2141 | SendPos(555) 2142 | Return 2143 | ;: >>选择传输模式{{{2 2144 | : 2145 | SendPos(556) 2146 | Return 2147 | ;: >>添加到下载列表{{{2 2148 | : 2149 | SendPos(557) 2150 | Return 2151 | ;: >>按列表下载{{{2 2152 | : 2153 | SendPos(558) 2154 | Return 2155 | ;导航 ========================================= 2156 | Return 2157 | ;: >>后退{{{2 2158 | : 2159 | SendPos(570) 2160 | Return 2161 | ;: >>前进{{{2 2162 | : 2163 | SendPos(571) 2164 | Return 2165 | ;: >>文件夹历史记录{{{2 2166 | : 2167 | Vim_HotkeyCount := 0 2168 | SendPos(572) 2169 | Return 2170 | ;: >>后退(非 FTP){{{2 2171 | : 2172 | SendPos(573) 2173 | Return 2174 | ;: >>前进(非 FTP){{{2 2175 | : 2176 | SendPos(574) 2177 | Return 2178 | ;: >>常用文件夹{{{2 2179 | : 2180 | Vim_HotkeyCount := 0 2181 | SendPos(526) 2182 | Return 2183 | ;: >>转到根文件夹{{{2 2184 | : 2185 | SendPos(2001) 2186 | Return 2187 | ;: >>转到上层文件夹{{{2 2188 | : 2189 | SendPos(2002) 2190 | Return 2191 | ;: >>打开光标处的文件夹或压缩包{{{2 2192 | : 2193 | SendPos(2003) 2194 | Return 2195 | ;: >>桌面{{{2 2196 | : 2197 | SendPos(2121) 2198 | Return 2199 | ;: >>我的电脑{{{2 2200 | : 2201 | SendPos(2122) 2202 | Return 2203 | ;: >>控制面板{{{2 2204 | : 2205 | SendPos(2123) 2206 | Return 2207 | ;: >>字体{{{2 2208 | : 2209 | SendPos(2124) 2210 | Return 2211 | ;: >>网上邻居{{{2 2212 | : 2213 | SendPos(2125) 2214 | Return 2215 | ;: >>打印机{{{2 2216 | : 2217 | SendPos(2126) 2218 | Return 2219 | ;: >>回收站{{{2 2220 | : 2221 | SendPos(2127) 2222 | Return 2223 | ;: >>更改文件夹{{{2 2224 | : 2225 | SendPos(500) 2226 | Return 2227 | ;: >>在左窗口打开光标处的文件夹或压缩包{{{2 2228 | : 2229 | SendPos(2024) 2230 | Return 2231 | ;: >>在右窗口打开光标处的文件夹或压缩包{{{2 2232 | : 2233 | SendPos(2025) 2234 | Return 2235 | ;: >>编辑来源窗口的路径{{{2 2236 | : 2237 | SendPos(2912) 2238 | Return 2239 | ;: >>光标移到列表中的第一个文件{{{2 2240 | : 2241 | SendPos(2050) 2242 | Return 2243 | ;: >>转到下一个驱动器{{{2 2244 | : 2245 | SendPos(2051) 2246 | Return 2247 | ;: >>转到上一个驱动器{{{2 2248 | : 2249 | SendPos(2052) 2250 | Return 2251 | ;: >>转到下一个选中的文件{{{2 2252 | : 2253 | SendPos(2053) 2254 | Return 2255 | ;: >>转到上一个选中的文件{{{2 2256 | : 2257 | SendPos(2054) 2258 | Return 2259 | ;: >>转到驱动器 A{{{2 2260 | : 2261 | SendPos(2061) 2262 | Return 2263 | ;: >>转到驱动器 C{{{2 2264 | : 2265 | SendPos(2063) 2266 | Return 2267 | ;: >>转到驱动器 D{{{2 2268 | : 2269 | SendPos(2064) 2270 | Return 2271 | ;: >>转到驱动器 E{{{2 2272 | : 2273 | SendPos(2065) 2274 | Return 2275 | ;: >>可自定义其他驱动器{{{2 2276 | : 2277 | SendPos(2066) 2278 | Return 2279 | ;: >>最多 26 个{{{2 2280 | : 2281 | SendPos(2086) 2282 | Return 2283 | ;帮助 ========================================= 2284 | Return 2285 | ;: >>帮助索引{{{2 2286 | : 2287 | SendPos(610) 2288 | Return 2289 | ;: >>快捷键列表{{{2 2290 | : 2291 | SendPos(620) 2292 | Return 2293 | ;: >>注册信息{{{2 2294 | : 2295 | SendPos(630) 2296 | Return 2297 | ;: >>访问 Totalcmd 网站{{{2 2298 | : 2299 | SendPos(640) 2300 | Return 2301 | ;: >>关于 Total Commander{{{2 2302 | : 2303 | SendPos(690) 2304 | Return 2305 | ;窗口 ========================================= 2306 | Return 2307 | ;: >>退出 Total Commander{{{2 2308 | : 2309 | SendPos(24340) 2310 | Return 2311 | ;: >>最小化 Total Commander{{{2 2312 | : 2313 | SendPos(2000) 2314 | Return 2315 | ;: >>最大化 Total Commander{{{2 2316 | : 2317 | SendPos(2015) 2318 | Return 2319 | ;: >>恢复正常大小{{{2 2320 | : 2321 | SendPos(2016) 2322 | Return 2323 | ;命令行 ========================================= 2324 | Return 2325 | ;: >>清除命令行{{{2 2326 | : 2327 | SendPos(2004) 2328 | Return 2329 | ;: >>下一条命令{{{2 2330 | : 2331 | SendPos(2005) 2332 | Return 2333 | ;: >>上一条命令{{{2 2334 | : 2335 | SendPos(2006) 2336 | Return 2337 | ;: >>将路径复制到命令行{{{2 2338 | : 2339 | SendPos(2019) 2340 | Return 2341 | ;工具 ========================================= 2342 | Return 2343 | ;: >>批量重命名{{{2 2344 | : 2345 | SendPos(2400) 2346 | Return 2347 | ;: >>系统信息{{{2 2348 | : 2349 | SendPos(506) 2350 | Return 2351 | ;: >>后台传输管理器{{{2 2352 | : 2353 | SendPos(559) 2354 | Return 2355 | ;: >>搜索文件{{{2 2356 | : 2357 | SendPos(501) 2358 | Return 2359 | ; : >> 搜索文件(单独进程) {{{2 2360 | : 2361 | SendPos(545) 2362 | return 2363 | ;: >>同步文件夹{{{2 2364 | : 2365 | SendPos(2020) 2366 | Return 2367 | ;: >>文件关联{{{2 2368 | : 2369 | SendPos(507) 2370 | Return 2371 | ;: >>定义内部关联{{{2 2372 | : 2373 | SendPos(519) 2374 | Return 2375 | ;: >>比较文件内容{{{2 2376 | : 2377 | SendPos(2022) 2378 | Return 2379 | ;: >>使用内部比较程序{{{2 2380 | : 2381 | SendPos(2040) 2382 | Return 2383 | ;: >>浏览内部命令{{{2 2384 | : 2385 | SendPos(2924) 2386 | Return 2387 | ;视图 ========================================= 2388 | Return 2389 | ;: >>显示/隐藏: 工具栏{{{2 2390 | : 2391 | SendPos(2901) 2392 | Return 2393 | ;: >>显示/隐藏: 驱动器按钮{{{2 2394 | : 2395 | SendPos(2902) 2396 | Return 2397 | ;: >>显示/隐藏: 两个驱动器按钮栏{{{2 2398 | : 2399 | SendPos(2903) 2400 | Return 2401 | ;: >>切换: 平坦/立体驱动器按钮{{{2 2402 | : 2403 | SendPos(2904) 2404 | Return 2405 | ;: >>切换: 平坦/立体用户界面{{{2 2406 | : 2407 | SendPos(2905) 2408 | Return 2409 | ;: >>显示/隐藏: 驱动器列表{{{2 2410 | : 2411 | SendPos(2906) 2412 | Return 2413 | ;: >>显示/隐藏: 当前文件夹{{{2 2414 | : 2415 | SendPos(2907) 2416 | Return 2417 | ;: >>显示/隐藏: 路径导航栏{{{2 2418 | : 2419 | SendPos(2926) 2420 | Return 2421 | ;: >>显示/隐藏: 排序制表符{{{2 2422 | : 2423 | SendPos(2908) 2424 | Return 2425 | ;: >>显示/隐藏: 状态栏{{{2 2426 | : 2427 | SendPos(2909) 2428 | Return 2429 | ;: >>显示/隐藏: 命令行{{{2 2430 | : 2431 | SendPos(2910) 2432 | Return 2433 | ;: >>显示/隐藏: 功能键按钮{{{2 2434 | : 2435 | SendPos(2911) 2436 | Return 2437 | ;: >>显示文件提示{{{2 2438 | : 2439 | SendPos(2914) 2440 | Return 2441 | ;: >>显示快速搜索窗口{{{2 2442 | : 2443 | SendPos(2915) 2444 | Return 2445 | ;: >>开启/关闭: 长文件名显示{{{2 2446 | : 2447 | SendPos(2010) 2448 | Return 2449 | ;: >>刷新来源窗口{{{2 2450 | : 2451 | SendPos(540) 2452 | Return 2453 | ;: >>仅显示选中的文件{{{2 2454 | : 2455 | SendPos(2023) 2456 | Return 2457 | ;: >>开启/关闭: 隐藏或系统文件显示{{{2 2458 | : 2459 | SendPos(2011) 2460 | Return 2461 | ;: >>开启/关闭: 8.3 式文件名小写显示{{{2 2462 | : 2463 | SendPos(2013) 2464 | Return 2465 | ;: >>开启/关闭: 文件夹按名称排序{{{2 2466 | : 2467 | SendPos(2012) 2468 | Return 2469 | ;: >>展开所有文件夹{{{2 2470 | : 2471 | SendPos(2026) 2472 | Return 2473 | ;: >>只展开选中的文件夹{{{2 2474 | : 2475 | SendPos(2046) 2476 | Return 2477 | ;: >>窗口分隔栏位于 50%{{{2 2478 | : 2479 | SendPos(909) 2480 | Return 2481 | ;: >>窗口分隔栏位于 100%{{{2 2482 | : 2483 | SendPos(910) 2484 | Return 2485 | ;: >>显示/隐藏: 文件夹标签{{{2 2486 | : 2487 | SendPos(2916) 2488 | Return 2489 | ;: >>显示/隐藏: XP 主题背景{{{2 2490 | : 2491 | SendPos(2923) 2492 | Return 2493 | ;: >>开启/关闭: 叠置图标显示{{{2 2494 | : 2495 | SendPos(2917) 2496 | Return 2497 | ;: >>显示/隐藏: 文件夹历史记录和常用文件夹按钮{{{2 2498 | : 2499 | SendPos(2919) 2500 | Return 2501 | ;: >>启用/禁用: 文件夹自动刷新{{{2 2502 | : 2503 | SendPos(2921) 2504 | Return 2505 | ;: >>启用/禁用: 自定义隐藏文件{{{2 2506 | : 2507 | SendPos(2922) 2508 | Return 2509 | ;: >>开启/关闭: 32 位 system32 目录重定向(64 位 Windows){{{2 2510 | : 2511 | SendPos(2925) 2512 | Return 2513 | ;: >>关闭独立文件夹树面板{{{2 2514 | : 2515 | SendPos(3200) 2516 | Return 2517 | ;: >>一个独立文件夹树面板{{{2 2518 | : 2519 | SendPos(3201) 2520 | Return 2521 | ;: >>两个独立文件夹树面板{{{2 2522 | : 2523 | SendPos(3202) 2524 | Return 2525 | ;: >>切换独立文件夹树面板状态{{{2 2526 | : 2527 | SendPos(3203) 2528 | Return 2529 | ;: >>开启/关闭: 一个独立文件夹树面板{{{2 2530 | : 2531 | SendPos(3204) 2532 | Return 2533 | ;: >>开启/关闭: 两个独立文件夹树面板{{{2 2534 | : 2535 | SendPos(3205) 2536 | Return 2537 | ;用户 ========================================= 2538 | Return 2539 | ;: >>用户菜单 1{{{2 2540 | : 2541 | SendPos(701) 2542 | Return 2543 | ;: >>用户菜单 2{{{2 2544 | : 2545 | SendPos(702) 2546 | Return 2547 | ;: >>用户菜单 3{{{2 2548 | : 2549 | SendPos(703) 2550 | Return 2551 | ;: >>...{{{2 2552 | : 2553 | SendPos(704) 2554 | Return 2555 | ;: >>5{{{2 2556 | : 2557 | SendPos(70) 2558 | Return 2559 | ;: >>6{{{2 2560 | : 2561 | SendPos(70) 2562 | Return 2563 | ;: >>7{{{2 2564 | : 2565 | SendPos(70) 2566 | Return 2567 | ;: >>8{{{2 2568 | : 2569 | SendPos(70) 2570 | Return 2571 | ;: >>9{{{2 2572 | : 2573 | SendPos(70) 2574 | Return 2575 | ;: >>可定义其他用户菜单{{{2 2576 | : 2577 | SendPos(710) 2578 | Return 2579 | ;标签 ========================================= 2580 | Return 2581 | ;: >>新建标签{{{2 2582 | : 2583 | SendPos(3001) 2584 | Return 2585 | ;: >>新建标签(在后台){{{2 2586 | : 2587 | SendPos(3002) 2588 | Return 2589 | ;: >>新建标签(并打开光标处的文件夹){{{2 2590 | : 2591 | SendPos(3003) 2592 | Return 2593 | ;: >>新建标签(在另一窗口打开文件夹){{{2 2594 | : 2595 | SendPos(3004) 2596 | Return 2597 | ;: >>下一个标签(Ctrl+Tab){{{2 2598 | : 2599 | SendPos(3005) 2600 | Return 2601 | ;: >>上一个标签(Ctrl+Shift+Tab){{{2 2602 | : 2603 | SendPos(3006) 2604 | Return 2605 | ;: >>关闭当前标签{{{2 2606 | : 2607 | SendPos(3007) 2608 | Return 2609 | ;: >>关闭所有标签{{{2 2610 | : 2611 | SendPos(3008) 2612 | Return 2613 | ;: >>显示标签菜单{{{2 2614 | : 2615 | SendPos(3009) 2616 | Return 2617 | ;: >>锁定/解锁当前标签{{{2 2618 | : 2619 | SendPos(3010) 2620 | Return 2621 | ;: >>锁定/解锁当前标签(可更改文件夹){{{2 2622 | : 2623 | SendPos(3012) 2624 | Return 2625 | ;: >>交换左右窗口及其标签{{{2 2626 | : 2627 | SendPos(535) 2628 | Return 2629 | ;: >>转到锁定标签的根文件夹{{{2 2630 | : 2631 | SendPos(3011) 2632 | Return 2633 | ;: >>来源窗口: 激活标签 1{{{2 2634 | : 2635 | SendPos(5001) 2636 | Return 2637 | ;: >>来源窗口: 激活标签 2{{{2 2638 | : 2639 | SendPos(5002) 2640 | Return 2641 | ;: >>...{{{2 2642 | : 2643 | SendPos(5003) 2644 | Return 2645 | ;: >>最多 99 个{{{2 2646 | : 2647 | SendPos(5004) 2648 | Return 2649 | ;: >>5{{{2 2650 | : 2651 | SendPos(5005) 2652 | Return 2653 | ;: >>6{{{2 2654 | : 2655 | SendPos(5006) 2656 | Return 2657 | ;: >>7{{{2 2658 | : 2659 | SendPos(5007) 2660 | Return 2661 | ;: >>8{{{2 2662 | : 2663 | SendPos(5008) 2664 | Return 2665 | ;: >>9{{{2 2666 | : 2667 | SendPos(5009) 2668 | Return 2669 | ;: >>0{{{2 2670 | : 2671 | SendPos(5010) 2672 | Return 2673 | ;: >>目标窗口: 激活标签 1{{{2 2674 | : 2675 | SendPos(5101) 2676 | Return 2677 | ;: >>目标窗口: 激活标签 2{{{2 2678 | : 2679 | SendPos(5102) 2680 | Return 2681 | ;: >>...{{{2 2682 | : 2683 | SendPos(5103) 2684 | Return 2685 | ;: >>最多 99 个{{{2 2686 | : 2687 | SendPos(5104) 2688 | Return 2689 | ;: >>5{{{2 2690 | : 2691 | SendPos(5105) 2692 | Return 2693 | ;: >>6{{{2 2694 | : 2695 | SendPos(5106) 2696 | Return 2697 | ;: >>7{{{2 2698 | : 2699 | SendPos(5107) 2700 | Return 2701 | ;: >>8{{{2 2702 | : 2703 | SendPos(5108) 2704 | Return 2705 | ;: >>9{{{2 2706 | : 2707 | SendPos(5109) 2708 | Return 2709 | ;: >>0{{{2 2710 | : 2711 | SendPos(5110) 2712 | Return 2713 | ;: >>左窗口: 激活标签 1{{{2 2714 | : 2715 | SendPos(5201) 2716 | Return 2717 | ;: >>左窗口: 激活标签 2{{{2 2718 | : 2719 | SendPos(5202) 2720 | Return 2721 | ;: >>...{{{2 2722 | : 2723 | SendPos(5203) 2724 | Return 2725 | ;: >>最多 99 个{{{2 2726 | : 2727 | SendPos(5204) 2728 | Return 2729 | ;: >>5{{{2 2730 | : 2731 | SendPos(5205) 2732 | Return 2733 | ;: >>6{{{2 2734 | : 2735 | SendPos(5206) 2736 | Return 2737 | ;: >>7{{{2 2738 | : 2739 | SendPos(5207) 2740 | Return 2741 | ;: >>8{{{2 2742 | : 2743 | SendPos(5208) 2744 | Return 2745 | ;: >>9{{{2 2746 | : 2747 | SendPos(5209) 2748 | Return 2749 | ;: >>0{{{2 2750 | : 2751 | SendPos(5210) 2752 | Return 2753 | ;: >>右窗口: 激活标签 1{{{2 2754 | : 2755 | SendPos(5301) 2756 | Return 2757 | ;: >>右窗口: 激活标签 2{{{2 2758 | : 2759 | SendPos(5302) 2760 | Return 2761 | ;: >>...{{{2 2762 | : 2763 | SendPos(5303) 2764 | Return 2765 | ;: >>最多 99 个{{{2 2766 | : 2767 | SendPos(5304) 2768 | Return 2769 | ;: >>5{{{2 2770 | : 2771 | SendPos(5305) 2772 | Return 2773 | ;: >>6{{{2 2774 | : 2775 | SendPos(5306) 2776 | Return 2777 | ;: >>7{{{2 2778 | : 2779 | SendPos(5307) 2780 | Return 2781 | ;: >>8{{{2 2782 | : 2783 | SendPos(5308) 2784 | Return 2785 | ;: >>9{{{2 2786 | : 2787 | SendPos(5309) 2788 | Return 2789 | ;: >>0{{{2 2790 | : 2791 | SendPos(5310) 2792 | Return 2793 | ;排序 ========================================= 2794 | Return 2795 | ;: >>来源窗口: 按第 1 列排序{{{2 2796 | : 2797 | SendPos(6001) 2798 | Return 2799 | ;: >>来源窗口: 按第 2 列排序{{{2 2800 | : 2801 | SendPos(6002) 2802 | Return 2803 | ;: >>...{{{2 2804 | : 2805 | SendPos(6003) 2806 | Return 2807 | ;: >>最多 99 列{{{2 2808 | : 2809 | SendPos(6004) 2810 | Return 2811 | ;: >>5{{{2 2812 | : 2813 | SendPos(6005) 2814 | Return 2815 | ;: >>6{{{2 2816 | : 2817 | SendPos(6006) 2818 | Return 2819 | ;: >>7{{{2 2820 | : 2821 | SendPos(6007) 2822 | Return 2823 | ;: >>8{{{2 2824 | : 2825 | SendPos(6008) 2826 | Return 2827 | ;: >>9{{{2 2828 | : 2829 | SendPos(6009) 2830 | Return 2831 | ;: >>0{{{2 2832 | : 2833 | SendPos(6010) 2834 | Return 2835 | ;: >>9{{{2 2836 | : 2837 | SendPos(6099) 2838 | Return 2839 | ;: >>目标窗口: 按第 1 列排序{{{2 2840 | : 2841 | SendPos(6101) 2842 | Return 2843 | ;: >>目标窗口: 按第 2 列排序{{{2 2844 | : 2845 | SendPos(6102) 2846 | Return 2847 | ;: >>...{{{2 2848 | : 2849 | SendPos(6103) 2850 | Return 2851 | ;: >>最多 99 列{{{2 2852 | : 2853 | SendPos(6104) 2854 | Return 2855 | ;: >>5{{{2 2856 | : 2857 | SendPos(6105) 2858 | Return 2859 | ;: >>6{{{2 2860 | : 2861 | SendPos(6106) 2862 | Return 2863 | ;: >>7{{{2 2864 | : 2865 | SendPos(6107) 2866 | Return 2867 | ;: >>8{{{2 2868 | : 2869 | SendPos(6108) 2870 | Return 2871 | ;: >>9{{{2 2872 | : 2873 | SendPos(6109) 2874 | Return 2875 | ;: >>0{{{2 2876 | : 2877 | SendPos(6110) 2878 | Return 2879 | ;: >>9{{{2 2880 | : 2881 | SendPos(6199) 2882 | Return 2883 | ;: >>左窗口: 按第 1 列排序{{{2 2884 | : 2885 | SendPos(6201) 2886 | Return 2887 | ;: >>左窗口: 按第 2 列排序{{{2 2888 | : 2889 | SendPos(6202) 2890 | Return 2891 | ;: >>...{{{2 2892 | : 2893 | SendPos(6203) 2894 | Return 2895 | ;: >>最多 99 列{{{2 2896 | : 2897 | SendPos(6204) 2898 | Return 2899 | ;: >>5{{{2 2900 | : 2901 | SendPos(6205) 2902 | Return 2903 | ;: >>6{{{2 2904 | : 2905 | SendPos(6206) 2906 | Return 2907 | ;: >>7{{{2 2908 | : 2909 | SendPos(6207) 2910 | Return 2911 | ;: >>8{{{2 2912 | : 2913 | SendPos(6208) 2914 | Return 2915 | ;: >>9{{{2 2916 | : 2917 | SendPos(6209) 2918 | Return 2919 | ;: >>0{{{2 2920 | : 2921 | SendPos(6210) 2922 | Return 2923 | ;: >>9{{{2 2924 | : 2925 | SendPos(6299) 2926 | Return 2927 | ;: >>右窗口: 按第 1 列排序{{{2 2928 | : 2929 | SendPos(6301) 2930 | Return 2931 | ;: >>右窗口: 按第 2 列排序{{{2 2932 | : 2933 | SendPos(6302) 2934 | Return 2935 | ;: >>...{{{2 2936 | : 2937 | SendPos(6303) 2938 | Return 2939 | ;: >>最多 99 列{{{2 2940 | : 2941 | SendPos(6304) 2942 | Return 2943 | ;: >>5{{{2 2944 | : 2945 | SendPos(6305) 2946 | Return 2947 | ;: >>6{{{2 2948 | : 2949 | SendPos(6306) 2950 | Return 2951 | ;: >>7{{{2 2952 | : 2953 | SendPos(6307) 2954 | Return 2955 | ;: >>8{{{2 2956 | : 2957 | SendPos(6308) 2958 | Return 2959 | ;: >>9{{{2 2960 | : 2961 | SendPos(6309) 2962 | Return 2963 | ;: >>0{{{2 2964 | : 2965 | SendPos(6310) 2966 | Return 2967 | ;: >>9{{{2 2968 | : 2969 | SendPos(6399) 2970 | Return 2971 | ;自定义列视图 ========================================= 2972 | Return 2973 | ;: >>来源窗口: 自定义列视图 1{{{2 2974 | : 2975 | SendPos(271) 2976 | Return 2977 | ;: >>来源窗口: 自定义列视图 2{{{2 2978 | : 2979 | SendPos(272) 2980 | Return 2981 | ;: >>...{{{2 2982 | : 2983 | SendPos(273) 2984 | Return 2985 | ;: >>最多 29 个{{{2 2986 | : 2987 | SendPos(274) 2988 | Return 2989 | ;: >>5{{{2 2990 | : 2991 | SendPos(275) 2992 | Return 2993 | ;: >>6{{{2 2994 | : 2995 | SendPos(276) 2996 | Return 2997 | ;: >>7{{{2 2998 | : 2999 | SendPos(277) 3000 | Return 3001 | ;: >>8{{{2 3002 | : 3003 | SendPos(278) 3004 | Return 3005 | ;: >>9{{{2 3006 | : 3007 | SendPos(279) 3008 | Return 3009 | ;: >>左窗口: 自定义列视图 1{{{2 3010 | : 3011 | SendPos(710) 3012 | Return 3013 | ;: >>左窗口: 自定义列视图 2{{{2 3014 | : 3015 | SendPos(72) 3016 | Return 3017 | ;: >>...{{{2 3018 | : 3019 | SendPos(73) 3020 | Return 3021 | ;: >>最多 29 个{{{2 3022 | : 3023 | SendPos(74) 3024 | Return 3025 | ;: >>5{{{2 3026 | : 3027 | SendPos(75) 3028 | Return 3029 | ;: >>6{{{2 3030 | : 3031 | SendPos(76) 3032 | Return 3033 | ;: >>7{{{2 3034 | : 3035 | SendPos(77) 3036 | Return 3037 | ;: >>8{{{2 3038 | : 3039 | SendPos(78) 3040 | Return 3041 | ;: >>9{{{2 3042 | : 3043 | SendPos(79) 3044 | Return 3045 | ;: >>右窗口: 自定义列视图 1{{{2 3046 | : 3047 | SendPos(171) 3048 | Return 3049 | ;: >>右窗口: 自定义列视图 2{{{2 3050 | : 3051 | SendPos(172) 3052 | Return 3053 | ;: >>...{{{2 3054 | : 3055 | SendPos(173) 3056 | Return 3057 | ;: >>最多 29 个{{{2 3058 | : 3059 | SendPos(174) 3060 | Return 3061 | ;: >>5{{{2 3062 | : 3063 | SendPos(175) 3064 | Return 3065 | ;: >>6{{{2 3066 | : 3067 | SendPos(176) 3068 | Return 3069 | ;: >>7{{{2 3070 | : 3071 | SendPos(177) 3072 | Return 3073 | ;: >>8{{{2 3074 | : 3075 | SendPos(178) 3076 | Return 3077 | ;: >>9{{{2 3078 | : 3079 | SendPos(179) 3080 | Return 3081 | ;: >>来源窗口: 下一个自定义视图{{{2 3082 | : 3083 | SendPos(5501) 3084 | Return 3085 | ;: >>来源窗口: 上一个自定义视图{{{2 3086 | : 3087 | SendPos(5502) 3088 | Return 3089 | ;: >>目标窗口: 下一个自定义视图{{{2 3090 | : 3091 | SendPos(5503) 3092 | Return 3093 | ;: >>目标窗口: 上一个自定义视图{{{2 3094 | : 3095 | SendPos(5504) 3096 | Return 3097 | ;: >>左窗口: 下一个自定义视图{{{2 3098 | : 3099 | SendPos(5505) 3100 | Return 3101 | ;: >>左窗口: 上一个自定义视图{{{2 3102 | : 3103 | SendPos(5506) 3104 | Return 3105 | ;: >>右窗口: 下一个自定义视图{{{2 3106 | : 3107 | SendPos(5507) 3108 | Return 3109 | ;: >>右窗口: 上一个自定义视图{{{2 3110 | : 3111 | SendPos(5508) 3112 | Return 3113 | ;: >>所有文件都按需加载备注{{{2 3114 | : 3115 | SendPos(5512) 3116 | Return 3117 | ;: >>仅选中的文件按需加载备注{{{2 3118 | : 3119 | SendPos(5513) 3120 | Return 3121 | ;: >>停止后台加载备注{{{2 3122 | : 3123 | SendPos(5514) 3124 | Return 3125 | -------------------------------------------------------------------------------- /Plugins/totalcmd/totalcmd.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxinhong/VimDesktop/2b367ca7fb7a7bffdecdcbc5155270b636d3d10b/Plugins/totalcmd/totalcmd.ini -------------------------------------------------------------------------------- /Plugins/vimconfig/vimconfig.ahk: -------------------------------------------------------------------------------- 1 | vimconfig: 2 | vim.SetPlugin("VimConfig","Array","0.1","VimDesktop的配置界面") 3 | vim.SetAction("","打开VimDesktop配置界面") 4 | vim.SetAction("","打开VimDesktop配置界面") 5 | ;vim.SetAction("","打开VimDesktop配置界面") 6 | ;vim.SetMode("normal") 7 | ;vim.map("gp","") 8 | ;vim.map("gk","") 9 | ;vim.map("","") 10 | ;vim.map("","") 11 | return 12 | /* 13 | : 14 | menu,vimconfig_menu,add 15 | menu,vimconfig_menu,deleteall 16 | menu,vimconfig_menu,add,&Exit, 17 | GUI,vimconfig:Destroy 18 | GUI,vimconfig:Default 19 | GUI,vimconfig:Menu,vimconfig_menu 20 | GUI,vimconfig:Add,StatusBar 21 | GUI,vimconfig:Show,w700 h500 22 | return 23 | 24 | : 25 | { 26 | GUI,vimconfig_keymap:Destroy 27 | GUI,vimconfig_keymap:Default 28 | GUI,vimconfig_keymap:Font,s10,Microsoft YaHei 29 | GUI,vimconfig_keymap:Add,Text,x10 y13 ,热键(&K) 30 | GUI,vimconfig_keymap:Add,Edit,x70 y10 w240 r1 31 | GUI,vimconfig_keymap:Add,Button,x320 y8 w30 h30 ,&? 32 | GUI,vimconfig_keymap:Add,Text,x10 y48 ,动作(&L) 33 | GUI,vimconfig_keymap:Add,Edit,x70 y45 w240 r1 34 | GUI,vimconfig_keymap:Add,Button,x320 y43 w30 h30 g,&! 35 | ;GUI,vimconfig_keymap:Add,Button,x575 y350 w60 h65,保存(&S) 36 | GUI,vimconfig_keymap:show 37 | return 38 | } 39 | */ 40 | : 41 | { 42 | plist := "" 43 | GUI,vimconfig_plugin:Destroy 44 | GUI,vimconfig_plugin:Default 45 | GUI,vimconfig_plugin:Font,s10,Microsoft YaHei 46 | GUI,vimconfig_plugin:Add,ListView,x10 y10 w150 h400 grid altsubmit gvimconfig_LoadActions,插件 47 | for plugin , obj in vim.pluginlist 48 | LV_Add("",plugin) 49 | GUI,vimconfig_plugin:Add,ListView,x170 y10 w500 h400 grid altsubmit,序号|动作|描述 50 | LV_ModifyCol(1,"center") 51 | LV_ModifyCol(2,"center 200") 52 | LV_ModifyCol(3,"Left 400") 53 | GUI,vimconfig_plugin:Show 54 | return 55 | } 56 | 57 | vimconfig_LoadActions: 58 | { 59 | If A_GuiEvent = I 60 | { 61 | GUI,vimconfig_plugin:ListView,sysListview321 62 | LV_GetText(plugin,A_EventInfo) 63 | GUI,vimconfig_plugin:Default 64 | GUI,vimconfig_plugin:ListView,sysListview322 65 | idx:=1 66 | LV_Delete() 67 | for action , type in vim.ActionFromPlugin 68 | { 69 | If type = %plugin% 70 | { 71 | Desc := vim.GetAction(action) 72 | LV_Add("",idx,action,Desc.Comment) 73 | idx++ 74 | } 75 | } 76 | } 77 | return 78 | } 79 | : 80 | { 81 | menu,vimconfig_keymap_menu,add 82 | ;menu,vimconfig_keymap_menu,deleteall 83 | menu,vimconfig_keymap_menu,add,&Exit,vimconfig_keymap_exit 84 | 85 | GUI,vimconfig_keymap:Destroy 86 | GUI,vimconfig_keymap:Default 87 | GUI,vimconfig_keymap:Font,s10,Microsoft YaHei 88 | 89 | GUI,vimconfig_keymap:Add,GroupBox,x10 y10 w200 h270,窗口(&Q) 90 | GUI,vimconfig_keymap:Add,ListBox ,x20 y36 w180 R12 center gvimconfig_keymap_loadmodelist 91 | 92 | GUI,vimconfig_keymap:Add,GroupBox,x10 y290 w200 h140 ,模式(&M) 93 | GUI,vimconfig_keymap:Add,ListBox ,x20 y316 w180 R5 center gvimconfig_keymap_loadhotkey 94 | 95 | GUI,vimconfig_keymap:Add,GroupBox,x225 y10 w420 h420,热键定义(&V) 96 | GUI,vimconfig_keymap:Add,Listview,x235 y36 w400 h380 grid,热键|动作|描述 97 | /* 98 | GUI,vimconfig_keymap:Add,Text,x235 y309 ,过滤(&F) 99 | GUI,vimconfig_keymap:Add,Edit,x290 y307 w160 r1 100 | 101 | GUI,vimconfig_keymap:Add,Button,x465 y305 w80,添加(&A) 102 | GUI,vimconfig_keymap:Add,Button,x555 y305 w80,删除(&D) 103 | 104 | GUI,vimconfig_keymap:Add,Text,x235 y353 ,热键(&K) 105 | GUI,vimconfig_keymap:Add,Edit,x290 y350 w240 r1 106 | GUI,vimconfig_keymap:Add,Text,x235 y390 ,动作(&L) 107 | GUI,vimconfig_keymap:Add,Edit,x290 y387 w240 r1 108 | 109 | GUI,vimconfig_keymap:Add,Button,x535 y350 w30 h30 ;gvimconfig_keymap_exit,&? 110 | GUI,vimconfig_keymap:Add,Button,x535 y385 w30 h30 g,&> 111 | GUI,vimconfig_keymap:Add,Button,x575 y350 w60 h65 ;,保存(&S) 112 | 113 | GUI,vimconfig_keymap:Add,Statusbar 114 | GUI,vimconfig_keymap:Menu,vimconfig_keymap_menu 115 | */ 116 | 117 | LV_ModifyCol(1,"left 170") 118 | LV_ModifyCol(2,"center 180") 119 | LV_ModifyCol(3,"left 200") 120 | 121 | vimconfig_keymap_loadwinlist() 122 | vimconfig_keymap_loadhotkey(vimconfig_keymap_loadmodelist(thiswin)) 123 | 124 | GUI,vimconfig_keymap:show 125 | return 126 | } 127 | vimconfig_keymap_exit: 128 | { 129 | GUI,vimconfig_keymap:Destroy 130 | return 131 | } 132 | vimconfig_keymap_loadwinlist() 133 | { 134 | global vim 135 | list := "|全局" 136 | GUI,vimconfig_keymap:Default 137 | for win , obj in vim.winlist 138 | list .= "|" win 139 | GuiControl,,ListBox1,%list% 140 | } 141 | vimconfig_keymap_loadmodelist: 142 | vimconfig_keymap_loadmodelist() 143 | GUI,vimconfig_keymap:Default 144 | LV_delete() 145 | return 146 | vimconfig_keymap_loadmodelist(win="") 147 | { 148 | global vim 149 | GUI,vimconfig_keymap:Default 150 | If not strlen(win) 151 | ControlGet,win,Choice,,ListBox1 152 | If win = 全局 153 | winObj := vim.GetWin() 154 | Else 155 | winObj := vim.GetWin(win) 156 | for mode , obj in winobj.modeList 157 | mlist .= "|" mode 158 | GuiControl,,ListBox2,%mlist% 159 | return win 160 | } 161 | vimconfig_keymap_loadhotkey: 162 | GUI,vimconfig_keymap:Default 163 | ControlGet,win,Choice,,ListBox1 164 | win := RegExMatch(win,"^全局$") ? "" : win 165 | ControlGet,mode,Choice,,ListBox2 166 | vimconfig_keymap_loadhotkey(win,mode) 167 | return 168 | vimconfig_keymap_loadhotkey(win,mode="") 169 | { 170 | global vim 171 | If strlen(mode) 172 | { 173 | winObj := vim.GetWin(win) 174 | modeobj := winObj.modeList[mode] 175 | } 176 | Else 177 | modeobj := vim.GetMode(win) 178 | GUI,vimconfig_keymap:Default 179 | LV_delete() 180 | for key , i in modeobj.keymapList 181 | LV_Add("",Key,i,vim.GetAction(i).comment) 182 | } 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 项目主页迁移到: 2 | 3 | # [http://git.oschina.net/linxinhong/VimDesktop](http://git.oschina.net/linxinhong/VimDesktop) 4 | 5 | # VimDesktop是什么? 6 | 7 | VimDesktop 是一套基于AHK编辑的热键管理框架 8 | 9 | 可以做到: 10 | 11 | > 多个模式:如 Normal 模式 、Insert 模式、 Search模式 12 | 13 | > 不同模式下的同一热键对应不同功能。如 14 | 15 | > Normal 模式下: 16 | 17 | > a : 按下 a 添加块注释 18 | 19 | > Insert 模式下: 20 | 21 | > a : 按下 a 就是插入a 22 | 23 | > Search 模式下 : 24 | 25 | > a : 搜索特定的单词 26 | 27 | > 模式间可以自由转换,只需要少量代码。 28 | 29 | > 每个热键对应什么功能,自己写Label 即可。 30 | 31 | 32 | # VimDesktop已经做了哪些? 33 | 34 | VimDesktop支持插件化,现在初步支持 35 | + __TotalCommander__ 由[ViATc](http://xbeta.info/viatc.htm)进阶而来,将TC vim化,方便管理文件 36 | + __Everything__ 支持[Everything](http://xbeta.info/everything-search-tool.htm)上的vim化 37 | + 更多插件…… 38 | 39 | # VimDesktop要做些什么? 40 | + 完善帮助文档,让更多人可以编写自己的插件。vim your desktop 41 | + 增加更多的插件 42 | 43 | # 其它 44 | + 如果有问题可以发送邮件给我[StarRed](mailto:234653915@qq.com) 45 | + 或者加入群一起讨论 271105729 46 | + 如果可以,请捐赠支持lin.xh@live.cn(支付宝) 47 | -------------------------------------------------------------------------------- /check.ahk: -------------------------------------------------------------------------------- 1 | #NoTrayIcon 2 | #NoEnv 3 | FileEncoding,utf-8 4 | ExtensionsAHK := A_ScriptDir "\Lib\VIMD_Plugins.ahk" 5 | /*If Not FileExist(ExtensionsAHK) 6 | FileAppend,,%ExtensionsAHK% 7 | FileRead,Extensions,%ExtensionsAHK% 8 | ; 验证Extensions里Include的插件是否存在 9 | Loop,Parse,Extensions,`n,`r 10 | { 11 | If Not RegExMatch(A_LoopField,"i)^#include") 12 | Continue 13 | If FileExist(RegExReplace(A_LoopField,"i)^#include\s(\*i\s)?%A_ScriptDir%\\")) 14 | { 15 | Match := "\t" ToMatch(SubStr(A_LoopField,35)) "\t" 16 | If Not RegExMatch(ExtensionsNames,Match) 17 | NewExtensions .= A_LoopField "`r`n" 18 | ExtensionsNames .= A_Tab Substr(A_LoopField,35) A_Tab 19 | } 20 | } 21 | */ 22 | ; 清理无用#include 23 | Filedelete,%ExtensionsAHK% 24 | FileAppend,%NewExtensions%,%ExtensionsAHK% 25 | ; 查询是否有新插件加入 26 | Loop,%A_ScriptDir%\Plugins\*.*,2 27 | plugins .= "#include *i `%A_ScriptDir`%\plugins\" A_LoopFileName "\" A_LoopFileName ".ahk`n" 28 | FileAppend,%plugins%,%ExtensionsAHK% 29 | ; 保存修改时间 30 | SaveTime := "/*`r`n[ExtensionsTime]`r`n" 31 | Loop,%A_ScriptDir%\plugins\*.*,2 32 | { 33 | plugin := A_ScriptDir "\plugins\" A_LoopFileName "\" A_LoopFileName ".ahk" 34 | FileGetTime,ExtensionsTime,%plugin%,M 35 | SaveTime .= A_LoopFileName "=" ExtensionsTime "`r`n" 36 | } 37 | SaveTime .= "*/`r`n" 38 | FileAppend,%SaveTime%,%ExtensionsAHK% 39 | FileRead,Extensions,%ExtensionsAHK% 40 | Send_WM_COPYDATA("reload") 41 | Exit 42 | 43 | Send_WM_COPYDATA(StringToSend) 44 | { 45 | VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0) 46 | SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1) 47 | NumPut(SizeInBytes, CopyDataStruct, A_PtrSize) 48 | NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize) 49 | Prev_DetectHiddenWindows := A_DetectHiddenWindows 50 | Prev_TitleMatchMode := A_TitleMatchMode 51 | DetectHiddenWindows On 52 | SetTitleMatchMode 2 53 | iniRead,hwnd,%A_Temp%\vimd_auto.ini,auto,hwnd 54 | SendMessage, 0x4a, 0, &CopyDataStruct,, ahk_id %hwnd% 55 | DetectHiddenWindows %Prev_DetectHiddenWindows% 56 | SetTitleMatchMode %Prev_TitleMatchMode% 57 | return ErrorLevel 58 | } 59 | 60 | 61 | ToMatch(str){ 62 | str := RegExReplace(str,"\+|\?|\.|\*|\{|\}|\(|\)|\||\^|\$|\[|\]|\\","\$0") 63 | Return RegExReplace(str,"\s","\s") 64 | } 65 | ; ToReplace(str) {{{2 66 | ; 67 | ToReplace(str){ 68 | If RegExMatch(str,"\$") 69 | return Regexreplace(str,"\$","$$$$") 70 | Else 71 | Return str 72 | } 73 | -------------------------------------------------------------------------------- /example.ahk: -------------------------------------------------------------------------------- 1 | ; 文件名: example.ahk 2 | ; 功能: 提供class_vim.ahk的应用说明,可以直接运行,独立于VimDesktop,以记事本为例子。 3 | ; 作者: Array(linxinhong) 4 | ; 时间: 2015年2月5日 5 | 6 | 7 | 8 | ; 初始化class_vim 9 | vim := class_vim() 10 | 11 | ; 运行Notepad作为示例 12 | run,notepad.exe "%A_ScriptFullPath%" 13 | WinWait,ahk_class Notepad 14 | msgbox 按h或者gg查看帮助 15 | ; 加载Action 16 | { 17 | ; 加载名为的Action,备注为向下移动,默认为GoSub对与Action名一致的Label,即 18 | vim.SetAction("","向下移动") 19 | vim.SetAction("","向上移动") 20 | vim.SetAction("","向左移动") 21 | vim.SetAction("","向右移动") 22 | vim.SetAction("","插入模式") 23 | vim.SetAction("","普通模式") 24 | ; 可以设置Action热键执行的是函数、命令行或者发送文本、执行的最大次数 25 | act := vim.SetAction("帮助","这是帮助内容") 26 | ; 设置Action为执行函数"msgbox_help" 27 | act.SetFunction("msgbox_help") 28 | /* 29 | ; 设置运行的次数为3次 30 | act.SetMaxTimes(3) 31 | 32 | ; 设置Action为运行命令行 cmd.exe 33 | act.setCmdLine("cmd.exe") 34 | 35 | ; 设置Action为发送文本" this is vimd" 36 | act.setHotString("this is vimd") 37 | 38 | Action执行的功能只能是Label/function/cmdline/hotstring.其中的一种,建议使用Lable或者function。方便修改 39 | */ 40 | } 41 | 42 | class:="Notepad" 43 | filepath:="Notepad.exe" 44 | ;filepath:="AAuto Quicker.exe" 45 | 46 | ; 在VimD中,filepath会作为ahk_exe 的判断条件,class作为ahk_class的判断条件 47 | ; 但是filepath的优先级更高 48 | 49 | 50 | 51 | ; 设置Win 52 | vim.SetWin("记事本",class,filepath) 53 | 54 | ; 切换到Inert模式,后续map的所有热键都是在Insert模式下 55 | vim.SetMode("Insert","记事本") 56 | ; 映射热键 57 | vim.map("","","记事本") 58 | 59 | ; 切换到Normal模式,后续map的所有热键都是在Noraml模式下 60 | vim.SetMode("Normal","记事本") 61 | ; 映射热键 62 | ; <0>~<9>是内置的Label,可以看一下class_vim.ahk 63 | vim.map("0","<0>","记事本") 64 | vim.map("1","<1>","记事本") 65 | vim.map("2","<2>","记事本") 66 | vim.map("3","<3>","记事本") 67 | vim.map("4","<4>","记事本") 68 | vim.map("5","<5>","记事本") 69 | vim.map("6","<6>","记事本") 70 | vim.map("7","<7>","记事本") 71 | vim.map("8","<8>","记事本") 72 | vim.map("9","<9>","记事本") 73 | vim.map("j","","记事本") 74 | vim.map("k","","记事本") 75 | vim.map("h","","记事本") 76 | vim.map("l","","记事本") 77 | ; 组合键,按g,再按g 78 | vim.map("gg","帮助","记事本") 79 | vim.map("h","帮助","记事本") 80 | vim.map("i","","记事本") 81 | 82 | ; 注意,最后一次SetMode 为 "normal" 则当前为Noraml模式 83 | 84 | return 85 | 86 | 87 | ; 以下为热键对应的功能区 88 | ; 切换为Insert 模式 89 | : 90 | vim.SetMode("Insert","记事本") 91 | return 92 | ; 切换为Normal 模式 93 | : 94 | vim.SetMode("Normal","记事本") 95 | return 96 | 97 | : 98 | send,{down} 99 | return 100 | : 101 | send,{up} 102 | return 103 | : 104 | send,{left} 105 | return 106 | : 107 | send,{right} 108 | return 109 | 110 | msgbox_help() 111 | { 112 | v = 113 | ( 114 | 按0~9是设置执行次数 115 | 按j为向下 116 | 按k为向上 117 | 按h为向左 118 | 按l为向右 119 | 按i切换到Insert模式 120 | 按Esc切换到Normal模式 121 | 按h或者gg查看帮助 122 | ) 123 | msgbox % v 124 | } 125 | 126 | 127 | ; class_vim必须放在最后 128 | #include lib\class_vim.ahk 129 | -------------------------------------------------------------------------------- /viatc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxinhong/VimDesktop/2b367ca7fb7a7bffdecdcbc5155270b636d3d10b/viatc.ico -------------------------------------------------------------------------------- /vimd.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxinhong/VimDesktop/2b367ca7fb7a7bffdecdcbc5155270b636d3d10b/vimd.ini -------------------------------------------------------------------------------- /vimdesktop.ahk: -------------------------------------------------------------------------------- 1 | Menu,Tray,Icon,%A_ScriptDir%\viatc.ico 2 | Menu,Tray,NoStandard 3 | Menu,Tray,Add,查看热键(&K), 4 | Menu,Tray,Add,查看插件(&P), 5 | Menu,Tray,Add, 6 | Menu,Tray,Add,重启(&R), 7 | Menu,Tray,Add,退出(&X), 8 | iniWrite,%A_ScriptHwnd%,%A_Temp%\vimd_auto.ini,auto,hwnd 9 | Global vim := class_vim() 10 | Global ini := class_EasyINI(A_ScriptDir "\vimd.ini") 11 | ;vim.Debug(true) 12 | CheckPlugin() 13 | CheckHotKey() 14 | OnMessage(0x4a, "Receive_WM_COPYDATA") 15 | return 16 | CheckPlugin() 17 | { 18 | ps := ini.GetKeys("Plugin") 19 | Loop,Parse,ps,`n 20 | vim.LoadPlugin(A_LoopField) 21 | } 22 | CheckHotKey() 23 | { 24 | secs := ini.GetSections() 25 | Loop,Parse,secs,`n 26 | { 27 | If RegExMatch(A_LoopField,"i)^((config)|(exclude)|(plugin))|(global)$") 28 | Continue 29 | Else 30 | { 31 | win := A_LoopField 32 | class := ini[win]["set class"] 33 | timeout := ini[win]["set timeout"] 34 | maxcount := ini[win]["set maxcount"] 35 | info := ini[win]["set info"] 36 | infoshow := ini[win]["set infoshow"] 37 | infohide := ini[win]["set infohide"] 38 | winObj := vim.SetWin(win,class) 39 | strlen(info) ? winObj.SetInfo(info) 40 | strlen(infoshow) ? winObj.SetShowInfo(infoshow) 41 | strlen(infohide) ? winObj.SetHideInfo(infoHide) 42 | strlen(timeout) ? vim.SetTimeOut(timeout,win) 43 | strlen(maxcount) ? vim.SetMaxCount(maxcount,win) 44 | ps := ini.GetKeys(win) 45 | Loop,Parse,ps,`n 46 | { 47 | If RegExMatch(A_LoopField,"i)^SET\s") 48 | Continue 49 | val:=ini[win][A_LoopField] 50 | If RegExMatch(val,"\[\=(.*)?\]",m) 51 | { 52 | If Strlen(m1) 53 | vim.SetMode(m1,win) 54 | val := Trim(RegExReplace(val,"\[=(.*)?\]")) 55 | } 56 | vim.map(A_LoopField,val,win) 57 | } 58 | } 59 | } 60 | } 61 | ; Receive_WM_COPYDATA(wParam, lParam) {{{2 62 | Receive_WM_COPYDATA(wParam, lParam){ 63 | StringAddress := NumGet(lParam + 2*A_PtrSize) ; 获取 CopyDataStruct 的 lpData 成员. 64 | AHKReturn := StrGet(StringAddress) ; 从结构中复制字符串. 65 | If RegExMatch(AHKReturn,"i)reload") 66 | { 67 | Settimer,VIMD_Reload,500 68 | return true 69 | } 70 | } 71 | VIMD_Reload: 72 | Reload 73 | return 74 | 75 | #Include %A_ScriptDir%\lib\class_EasyINI.ahk 76 | #Include %A_ScriptDir%\lib\class_vim.ahk 77 | #Include %A_ScriptDir%\lib\acc.ahk 78 | #Include %A_ScriptDir%\lib\dock.ahk 79 | #Include %A_ScriptDir%\lib\gdip.ahk 80 | #Include %A_ScriptDir%\Lib\VIMD_plugins.ahk 81 | --------------------------------------------------------------------------------