Skip to content

Instantly share code, notes, and snippets.

@TLMcode
Last active August 29, 2015 14:22
Show Gist options
  • Save TLMcode/e2955e489d46a203f000 to your computer and use it in GitHub Desktop.
Save TLMcode/e2955e489d46a203f000 to your computer and use it in GitHub Desktop.
#SingleInstance, Off
#NoEnv
SetBatchLines, -1
FilePath = C:\Windows\ShellNew\Template.ahk
DefaultName = %A_UserName%
DefaultDesc =
Indent := "`t"
Title = CodeQuickTester
Param1 = %1%
FilePath := Param1 ? RegExReplace(Param1, "^ahk:") : FilePath
if FileExist(FilePath)
Code := FileOpen(FilePath, "r").Read()
else if (FilePath ~= "^https?://")
Code := UrlDownloadToVar(FilePath)
Menu, Tray, Icon, %A_AhkPath%, 2
Shell := ComObjCreate("WScript.Shell")
FileEncoding, UTF-8
Menu, MenuBar, Add, &Save, SaveButton
Menu, MenuBar, Add, &Load, LoadButton
Menu, MenuBar, Add, &Fetch, FetchButton
Menu, MenuBar, Add, &Paste, PasteButton
Menu, MenuBar, Add, P&arams, ParamsButton
Menu, MenuBar, Add, Re&indent, IndentButton
Menu, MenuBar, Add, Install, ServiceHandler
Gui, Main:New, +Resize
Gui, Menu, MenuBar
Gui, Margin, 5, 5
Gui, Color,, 3F3F3F
Gui, Font, s10 cEDEDCD, Consolas
Gui, Add, Edit, vCodeEditor hWndhCodeEditor WantTab -Wrap HScroll t14 r2 ; t14 sets tab size to 4 characters
Gui, Font, s8, Microsoft Sans Serif
Gui, Add, Button, gRunButton vRun, &Run
Gui, Show, w640 h480, %Title%
Gui, Add, StatusBar
SB_SetParts(70, 70, 70)
LoadCode(Code)
OnMessage(0x100, "ProcessEditEvents") ; WM_KEYDOWN
OnMessage(0x201, "ProcessEditEvents") ; WM_LBUTTONDOWN
OnMessage(0x202, "ProcessEditEvents") ; WM_LBUTTONUP
OnMessage(0x204, "ProcessEditEvents") ; WM_RBUTTONDOWN
return
#If Exec.Status == 0
Escape::Exec.Terminate() ; CheckIfRunning updates the GUI
#If
ProcessEditEvents(wParam, lParam, Msg, hWnd)
{
global hCodeEditor
if (hWnd == hCodeEditor)
SetTimer, UpdateStatusBar, -0 ; Spawn new pseudo thread that will run after this function terminates
}
UpdateStatusBar()
{
global hCodeEditor
Gui, Main:Default
GuiControlGet, CodeEditor
SB_SetText("Len " StrLen(CodeEditor), 1)
ControlGet, Row, CurrentLine,,, ahk_id %hCodeEditor%
ControlGet, Col, CurrentCol,,, ahk_id %hCodeEditor%
SB_SetText("Line " Row, 2)
SB_SetText("Col " Col, 3)
ControlGet, Selected, Selected,,, ahk_id %hCodeEditor%
Len := StrLen(StrReplace(Selected, "`r`n", "`n"))
SB_SetText(Len ? "Selection Length: " Len : "", 4)
}
MainGuiClose:
GuiControlGet, CodeEditor
if !CodeEditor
ExitApp
MsgBox, 308, %Title%, Are you sure you want to exit?
IfMsgBox, Yes
ExitApp
return
MainGuiSize:
Critical
Process, Priority,, R
GuiControl, Move, CodeEditor, % "x" 5 "y" 5 "w" A_GuiWidth-10 "h" A_GuiHeight-60
ButtonWidth := (A_GuiWidth-10)
GuiControl, Move, Run, % "x" 5 "y" A_GuiHeight-50 "w" ButtonWidth "h" 22
SetTimer, Normal, -100
return
Normal:
Process, Priority,, N
return
MainGuiDropFiles:
LoadCode(FileOpen(StrSplit(A_GuiEvent, "`n")[1], "r").Read())
return
RunButton:
if (Exec.Status == 0) ; Running
Exec.Terminate() ; CheckIfRunning updates the GUI
else ; Not running or doesn't exist
{
GuiControlGet, CodeEditor, Main:
GuiControlGet, Params, Params:
Exec := ExecScript(CodeEditor, Params, DeHashBang(CodeEditor))
GuiControl, Main:, Run, &Kill
SetTimer, CheckIfRunning, 100
}
return
CheckIfRunning:
if (Exec.Status == 1)
{
SetTimer, CheckIfRunning, Off
GuiControl, Main:, Run, &Run
}
return
SaveButton:
Gui, +OwnDialogs
FileSelectFile, FilePath, S2
if ErrorLevel
return
GuiControlGet, CodeEditor
FileOpen(FilePath, "w").Write(CodeEditor)
return
LoadButton:
Gui, +OwnDialogs
FileSelectFile, FilePath, 3
if !ErrorLevel
LoadCode(FileOpen(FilePath, "r").Read())
return
FetchButton:
Gui, +OwnDialogs
InputBox, Url, %Title%, Enter a URL to fetch code from.
if (Url := Trim(Url))
LoadCode(UrlDownloadToVar(Url))
return
PasteButton:
Gui, Paste:New, +OwnerMain +ToolWindow
Gui, Margin, 5, 5
Gui, Font, s8, Microsoft Sans Serif
Gui, Add, Text, xm ym w30 h22 +0x200, Desc:
Gui, Add, Edit, x+5 yp w125 h22 vPasteDesc, %DefaultDesc%
Gui, Add, Button, x+4 yp-1 w52 h24 Default gPaste, Paste
Gui, Add, Text, xm y+5 w30 h22 +0x200, Name:
Gui, Add, Edit, x+5 yp w100 h22 vPasteName, %DefaultName%
Gui, Add, ComboBox, x+5 yp w75 vPasteChan hWndPasteChan, Announce||#ahk|#ahkscript
PostMessage, 0x153, -1, 22-6,, ahk_id %PasteChan% ; Set height of ComboBox
Gui, Show,, Paste
return
PasteGuiEscape:
Gui, Destroy
return
Paste:
Gui, Submit
Gui, Destroy
GuiControlGet, CodeEditor, Main:
Link := Ahkbin(CodeEditor, PasteName, PasteDesc, PasteChan)
MsgBox, 292, %Title%, Link acquired:`n%Link%`n`nCopy to clipboard?
IfMsgBox, Yes
Clipboard := Link
return
ParamsButton:
Gui, Params:New, +OwnerMain +ToolWindow
Gui, Margin, 5, 5
Gui, Font, s8, Microsoft Sans Serif
Gui, Add, Text, xm ym w300 h22 Center +0x200, Params will be cleared on window exit
Gui, Add, Edit, w300 h22 vParams
Gui, Show,, Command Line Params
return
ParamsGuiEscape:
Gui, Destroy
return
IndentButton:
GuiControlGet, CodeEditor, Main:
LoadCode(AutoIndent(CodeEditor, Indent))
return
ServiceHandler:
Gui, +OwnDialogs
if ServiceHandlerInstalled()
{
MsgBox, 36, , Are you sure you want to remove CodeQuickTester from being the default service handler for "ahk:" links?
IfMsgBox, Yes
RemoveServiceHandler()
}
else
{
MsgBox, 36, , Are you sure you want to install CodeQuickTester as the default service handler for "ahk:" links?
IfMsgBox, Yes
AddServiceHandler()
}
return
LoadCode(Code)
{
GuiControlGet, CodeEditor
if (CodeEditor && CodeEditor != Code)
{
MsgBox, 308, %Title%, Are you sure you want to overwrite your code?
IfMsgBox, No
return
}
GuiControl,, CodeEditor, %Code%
UpdateStatusBar()
}
UrlDownloadToVar(Url)
{
try
{
http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
http.Open("GET", Url, false), http.Send()
return http.ResponseText
}
catch
throw Exception("Something went wrong with the HTTP Request. Invalid URL?")
}
; Modified from https://github.com/cocobelgica/AutoHotkey-Util/blob/master/ExecScript.ahk
ExecScript(Script, Params="", AhkPath="")
{
Name := "AHK_CQT_" A_TickCount
Pipe := []
Loop, 2
{
Pipe[A_Index] := DllCall("CreateNamedPipe"
, "Str", "\\.\pipe\" name
, "UInt", 2, "UInt", 0
, "UInt", 255, "UInt", 0
, "UInt", 0, "UPtr", 0
, "UPtr", 0, "UPtr")
}
if !FileExist(AhkPath)
AhkPath := A_AhkPath
Call = "%AhkPath%" /CP65001 "\\.\pipe\%Name%"
Shell := ComObjCreate("WScript.Shell")
Exec := Shell.Exec(Call " " Params)
DllCall("ConnectNamedPipe", "UPtr", Pipe[1], "UPtr", 0)
DllCall("CloseHandle", "UPtr", Pipe[1])
DllCall("ConnectNamedPipe", "UPtr", Pipe[2], "UPtr", 0)
FileOpen(Pipe[2], "h", "UTF-8").Write(Script)
DllCall("CloseHandle", "UPtr", Pipe[2])
return Exec
}
Ahkbin(Content, Name="", Desc="", Channel="")
{
static URL := "http://p.ahkscript.org/"
Form := "code=" UriEncode(Content)
if Name
Form .= "&name=" UriEncode(Name)
if Desc
Form .= "&desc=" UriEncode(Desc)
if Channel
Form .= "&announce=on&channel=" UriEncode(Channel)
Pbin := ComObjCreate("WinHttp.WinHttpRequest.5.1")
Pbin.Open("POST", URL, False)
Pbin.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
Pbin.Send(Form)
return Pbin.Option(1)
}
; Modified by GeekDude from http://goo.gl/0a0iJq
UriEncode(Uri, RE="[0-9A-Za-z]") {
VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0), StrPut(Uri, &Var, "UTF-8")
While Code := NumGet(Var, A_Index - 1, "UChar")
Res .= (Chr:=Chr(Code)) ~= RE ? Chr : Format("%{:02X}", Code)
Return, Res
}
DeHashBang(Script)
{
AhkPath := A_AhkPath
if RegExMatch(Script, "`a)^\s*`;#!\s*(.+)", Match)
{
AhkPath := Trim(Match1)
Vars := {"%A_ScriptDir%": A_WorkingDir
, "%A_WorkingDir%": A_WorkingDir
, "%A_AppData%": A_AppData
, "%A_AppDataCommon%": A_AppDataCommon
, "%A_LineFile%": A_ScriptFullPath
, "%A_AhkPath%": A_AhkPath
, "%A_AhkDir%": A_AhkPath "\.."}
for SearchText, Replacement in Vars
StringReplace, AhkPath, AhkPath, %SearchText%, %Replacement%, All
}
return AhkPath
}
AddServiceHandler()
{
RegWrite, REG_SZ, HKCU, Software\Classes\ahk,, URL:AHK Script Protocol
RegWrite, REG_SZ, HKCU, Software\Classes\ahk, URL Protocol
RegWrite, REG_SZ, HKCU, Software\Classes\ahk\shell\open\command,, "%A_AhkPath%" "%A_ScriptFullPath%" "`%1"
}
RemoveServiceHandler()
{
RegDelete, HKCU, Software\Classes\ahk
}
ServiceHandlerInstalled()
{
RegRead, Out, HKCU, Software\Classes\ahk
return !ErrorLevel
}
AutoIndent(Code, Indent = "`t", Newline = "`n")
{
IndentRegEx =
( LTrim Join
Catch|else|for|Finally|if|IfEqual|IfExist|
IfGreater|IfGreaterOrEqual|IfInString|
IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|
IfNotExist|IfNotInString|IfWinActive|IfWinExist|
IfWinNotActive|IfWinNotExist|Loop|Try|while
)
; Lock and Block are modified ByRef by Current
Lock := [], Block := []
ParentIndent := Braces := 0
ParentIndentObj := []
for each, Line in StrSplit(Code, "`n", "`r")
{
Text := Trim(RegExReplace(Line, "\s;.*")) ; Comment removal
First := SubStr(Text, 1, 1), Last := SubStr(Text, 0, 1)
FirstTwo := SubStr(Text, 1, 2)
IsExpCont := (Text ~= "i)^\s*(&&|OR|AND|\.|\,|\|\||:|\?)")
IndentCheck := (Text ~= "iA)}?\s*\b(" IndentRegEx ")\b")
if (First == "(" && Last != ")")
Skip := True
if (Skip)
{
if (First == ")")
Skip := False
Out .= Newline . RTrim(Line)
continue
}
if (FirstTwo == "*/")
Block := [], ParentIndent := 0
if Block.MinIndex()
Current := Block, Cur := 1
else
Current := Lock, Cur := 0
; Round converts "" to 0
Braces := Round(Current[Current.MaxIndex()].Braces)
ParentIndent := Round(ParentIndentObj[Cur])
if (First == "}")
{
while ((Found := SubStr(Text, A_Index, 1)) ~= "}|\s")
{
if (Found ~= "\s")
continue
if (Cur && Current.MaxIndex() <= 1)
break
Special := Current.Pop().Ind, Braces--
}
}
if (First == "{" && ParentIndent)
ParentIndent--
Out .= Newline
Loop, % Special ? Special-1 : Round(Current[Current.MaxIndex()].Ind) + Round(ParentIndent)
Out .= Indent
Out .= Trim(Line)
if (FirstTwo == "/*")
{
if (!Block.MinIndex())
{
Block.Push({ParentIndent: ParentIndent
, Ind: Round(Lock[Lock.MaxIndex()].Ind) + 1
, Braces: Round(Lock[Lock.MaxIndex()].Braces) + 1})
}
Current := Block, ParentIndent := 0
}
if (Last == "{")
{
Braces++, ParentIndent := (IsExpCont && Last == "{") ? ParentIndent-1 : ParentIndent
Current.Push({Braces: Braces
, Ind: ParentIndent + Round(Current[Current.MaxIndex()].ParentIndent) + Braces
, ParentIndent: ParentIndent + Round(Current[Current.MaxIndex()].ParentIndent)})
ParentIndent := 0
}
if ((ParentIndent || IsExpCont || IndentCheck) && (IndentCheck && Last != "{"))
ParentIndent++
if (ParentIndent > 0 && !(IsExpCont || IndentCheck))
ParentIndent := 0
ParentIndentObj[Cur] := ParentIndent
Special := 0
}
if Braces
throw Exception("Segment Open!")
return SubStr(Out, StrLen(Newline)+1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment