[Editor] CodeQuickTester - Write and run code without saving to a temporary file

Post your working scripts, libraries and tools for AHK v1.1 and older
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

31 May 2015, 13:34

Whoops, looks like I broke the gist open button from the extension, fixed now. @BGM Check the original post, the greasemonkey script is in a spoiler tag about 2/3 the way down.

I've just updated the code tester as well.
  • Moved config to top of script
  • Added default file option to config (Defaults to ShellNew)
  • Made selected text length more responsive
  • Changed pastebin dropdown to combobox
  • Updated to new pastebin URL
  • Added A_AhkDir to the hashbang decoder
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

01 Jun 2015, 22:55

I'm going to go ahead and push this out. Introducing Auto Indent, modified from @maestrith's amazing AHK Studio!
  • Added menu button for Auto Indent
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: CodeQuickTester

02 Jun 2015, 09:59

You should add triple-click to select an entire line
User avatar
maestrith
Posts: 825
Joined: 16 Oct 2013, 13:52

Re: CodeQuickTester

02 Jun 2015, 10:01

aww :) you called Studio amazing :)
John H Wilson III 05/29/51 - 03/01/2020. You will be missed.AHK Studio OSDGUI Creator
Donations
Discord
All code is done on a 64 bit Windows 10 PC Running AutoHotkey x32
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

04 Jun 2015, 18:17

I just updated the code tester! This update brings the use of a RichEdit control. Also, I've added a hotkey for opening the help file. Kudos to @just_me for his help with the RE, and his wonderful RE class I used as a guide. Also thanks to @BGM for his feedback in the IRC.
  • Switched to using a RichEdit control
  • Triple click selects whole line
  • Added options for variable tab width, font, typeface, font color, bgcolor etc.
  • ^h to open help file
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

10 Aug 2015, 16:56

What do you guys think about switching to a more OOP code base? Here's an unfinished example

Code: Select all

#SingleInstance, Off
#NoEnv
SetBatchLines, -1

Menu, Tray, Icon, %A_AhkPath%, 2
FileEncoding, UTF-8

MyTester := new CodeQuickTester()
return

class CodeQuickTester
{
	static Msftedit := DllCall("LoadLibrary", "Str", "Msftedit.dll")
	
	__New()
	{
		this.DefaultPath := "C:\Windows\ShellNew\Template.ahk"
		this.DefaultName := "GeekDude"
		this.DefaultDesc := ""
		this.FGColor := 0xCDEDED
		this.BGColor := 0x3F3F3F
		this.TabSize := 4
		this.Indent := "`t"
		this.TypeFace := "Consolas"
		this.Font := "s9 wBold"
		this.Title := "CodeQuickTester"
		
		this.Shell := ComObjCreate("WScript.Shell")
		
		; TODO: This makes the class never get garbage collected. Oops!
		Buttons := new this.MenuButtons(this)
		Menu := 
		( Join
		[
			["&File", [
				["&Save`tCtrl+S", Buttons.Save.Bind(Buttons)],
				["&Open`tCtrl+O", Buttons.Open.Bind(Buttons)],
				["&Fetch", Buttons.Fetch.Bind(Buttons)]
			]], ["&Tools", [
				["&Paste`tCtrl+P", Buttons.Paste.Bind(Buttons)],
				["Re&indent", Buttons.Indent.Bind(Buttons)],
				["Install", Buttons.Install.Bind(Buttons)],
				["&Help`tF1", Buttons.Help.Bind(Buttons)]
			]]
		]
		)
		
		Gui, New, +Resize +hWndhMainWindow
		this.hMainWindow := hMainWindow
		Gui, Menu, % this.CreateMenuBar(Menu)
		Gui, Margin, 5, 5
		
		Gui, Font, % this.Font, % this.TypeFace
		
		this.InitRichEdit()
		
		Gui, Font, s8 w400 q0, Microsoft Sans Serif
		Gui, Add, Button, hWndhRunButton, &Run
		RunFunc := this.RunButton.Bind(this) ; TODO: This makes the class never get garbage collected. Oops!
		GuiControl, +g, %hRunButton%, %RunFunc%
		this.hRunButton := hRunButton
		Gui, Add, StatusBar
		SB_SetParts(70, 70, 70)
		
		WinEvents.Register(this.hMainWindow, new this.Events(this))		
		Gui, Show, w640 h480, % this.Title
	}
	
	InitRichEdit()
	{
		Gui, Add, Custom, ClassRichEdit50W hWndhWnd +0x5031b1c4 +E0x20000
		this.hCodeEditor := hWnd
		
		; Set background color
		SendMessage, 0x443, 0, this.BGColor,, ahk_id %hWnd% ; EM_SETBKGNDCOLOR
		
		; Set FG color
		VarSetCapacity(CharFormat, 116, 0)
		NumPut(116, CharFormat, 0, "UInt") ; cbSize := sizeOf(CHARFORMAT2)
		NumPut(0x40000000, CharFormat, 4, "UInt") ; dwMask := CFM_COLOR
		NumPut(this.FGColor, CharFormat, 20, "UInt") ; crTextColor := 0xBBGGRR
		SendMessage, 0x444, 0, &CharFormat,, ahk_id %hWnd% ; EM_SETCHARFORMAT
		
		; Set tab size to 4
		VarSetCapacity(TabStops, 4, 0), NumPut(this.TabSize*4, TabStops, "UInt")
		SendMessage, 0x0CB, 1, &TabStops,, ahk_id %hWnd% ; EM_SETTABSTOPS
		
		; Change text limit from 32,767 to max
		SendMessage, 0x435, 0, -1,, ahk_id %hWnd% ; EM_EXLIMITTEXT
		
		; Disable inconsistent formatting
		SendMessage, 0x4CC, 1, 1,, ahk_id %hWnd% ; EM_SETEDITSTYLE SES_EMULATESYSEDIT
	}
	
	CreateMenuBar(Menu)
	{
		static MenuName := 0
		MyMenuName := "CQT_" MenuName, MenuName++
		for each, Item in Menu
		{
			Ref := Item[2]
			if IsObject(Ref) && Ref._NewEnum()
				Ref := ":" this.CreateMenuBar(Ref)
			Menu, %MyMenuName%, Add, % Item[1], %Ref%
		}
		return MyMenuName
	}
	
	RunButton()
	{
		if (this.Exec.Status == 0) ; Running
			this.Exec.Terminate() ; CheckIfRunning updates the GUI
		else ; Not running or doesn't exist
		{
			GuiControlGet, CodeEditor,, % this.hCodeEditor
;			GuiControlGet, Params, Params:
			this.Exec := ExecScript(CodeEditor, "", DeHashBang(CodeEditor)) ; TODO: Implement Params
			GuiControl,, % this.hRunButton, &Kill
			
			BoundFunc := this.CheckIfRunning.Bind(this, Context := {})
			Context.BoundFunc := BoundFunc
			SetTimer, %BoundFunc%, 100
		}
	}
	
	CheckIfRunning(Context)
	{
		if (this.Exec.Status == 1)
		{
			BoundFunc := Context.BoundFunc
			SetTimer, %BoundFunc%, Delete
			GuiControl,, % this.hRunButton, &Run ; TODO: Make sure I don't have to specify default gui
		}
	}
	
	class MenuButtons
	{
		__New(Parent)
		{
			this.Parent := Parent
		}
		
		Save()
		{
			Gui, +OwnDialogs
			FileSelectFile, FilePath, S2
			if ErrorLevel
				return
			GuiControlGet, CodeEditor,, % this.Parent.hCodeEditor
			
			; TODO: Confirm before overwrite
			FileOpen(FilePath, "w").Write(CodeEditor)
		}
		
		Open()
		{
			; TODO
		}
		
		Fetch()
		{
			; TODO
		}
		
		Paste()
		{
			; TODO
		}
		
		Indent()
		{
			; TODO
		}
		
		Help()
		{
			Run, %A_AhkPath%\..\AutoHotkey.chm
		}
		
		Install()
		{
			; TODO
		}
	}
	
	class Events
	{
		__New(Parent)
		{
			this.Parent := Parent
		}
		
		Size()
		{
			ToolTip, hi
			GuiControl, Move, % this.Parent.hCodeEditor, % "x" 5 "y" 5 "w" A_GuiWidth-10 "h" A_GuiHeight-60
			ButtonWidth := (A_GuiWidth-10)
			GuiControl, Move, % this.Parent.hRunButton, % "x" 5 "y" A_GuiHeight-50 "w" ButtonWidth "h" 22
		}
		
		Close()
		{
			; TODO: Allow multiple instances?
			ExitApp
		}
	}
}

; TODO: Decide if I should keep a separate class for
; event dispatching or if I should handle it all inline.
class WinEvents ; static class
{
	static Table := {}
	
	Register(hWnd, Class)
	{
		Gui, +LabelWinEvents.
		this.Table[hWnd] := Class
	}
	
	Unregister(hWnd)
	{
		this.Table.Delete(hWnd)
	}
	
	Dispatch(hWnd, Type)
	{
		Class := this.Table[hWnd]
		
		; TODO: Decide if it should use a prefix for the method name
		Class[Type].Call(Class)
	}
	
	; These *CANNOT* be added dynamically or handled dynamically via __Call
	Close()
	{
		WinEvents.Dispatch(this, "Close")
	}
	
	Escape()
	{
		WinEvents.Dispatch(this, "Escape")
	}
	
	Size()
	{
		WinEvents.Dispatch(this, "Size")
	}
	
	ContextMenu()
	{
		WinEvents.Dispatch(this, "ContextMenu")
	}
	
	DropFiles()
	{
		WinEvents.Dispatch(this, "DropFiles")
	}
}

; 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
}

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
}
User avatar
dd900
Posts: 121
Joined: 27 Oct 2013, 16:03

Re: CodeQuickTester

10 Aug 2015, 23:46

Looks good. I just tested this with CodeQuickTester then I used the new instance to load another instance of CodeQuickTester.

CodeQuickTesterCeption
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

11 Aug 2015, 08:58

What effect do you think this new approach has on code readability?
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: CodeQuickTester

11 Aug 2015, 10:43

dd900 wrote:Looks good. I just tested this with CodeQuickTester then I used the new instance to load another instance of CodeQuickTester.

CodeQuickTesterCeption
:D
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
dd900
Posts: 121
Joined: 27 Oct 2013, 16:03

Re: CodeQuickTester

11 Aug 2015, 11:22

GeekDude wrote:What effect do you think this new approach has on code readability?
I think that would depend on the user. I myself find it easier to read the newer version, but that's only because I am familiar with how classes work in ahk (thank you lexikos). Someone with no experience using objects or classes in ahk or any other language might not understand what is going on in the code.

I say continue with the new OOP aproach
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

11 Aug 2015, 11:45

A fun side effect is that you can create multiple instances of the code editor from one script. That could make it easier for me to add a "open new instance" button that works while the script is being run dynamically.
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: CodeQuickTester

11 Aug 2015, 12:51

+1
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

17 Aug 2015, 11:18

Run this, and click the run button a few times. Works fine, right? Click the edit box, then click the run button a few more times. It gets stuck on "Kill". Now kill the script, and uncomment the two lines in the UpdateStatusBar method, and try again. Everything works fine. My question is why does that fix a seemingly unrelated problem? I'm baffled.

Code: Select all

#NoEnv
MyTester := new CodeQuickTester()

class CodeQuickTester
{
	__New()
	{
		this.Bound := []
		this.Bound.RunButton := this.RunButton.Bind(this)
		this.Bound.OnMessage := this.OnMessage.Bind(this)
		this.Bound.UpdateStatusBar := this.UpdateStatusBar.Bind(this)
		this.Bound.CheckIfRunning := this.CheckIfRunning.Bind(this)
		
		Gui, New, +Resize +hWndhMainWindow
		this.hMainWindow := hMainWindow
		
		Gui, Add, Edit, hWndhCodeEditor
		this.hCodeEditor := hCodeEditor
		
		Gui, Add, Button, hWndhRunButton, &Run
		this.hRunButton := hRunButton
		
		BoundFunc := this.Bound.RunButton
		GuiControl, +g, %hRunButton%, %BoundFunc%
		
		OnMessage(0x201, this.Bound.OnMessage)
		Gui, Show
	}
	
	RunButton()
	{
		GuiControl,, % this.hRunButton, &Kill
		
		BoundFunc := this.Bound.CheckIfRunning
		SetTimer, %BoundFunc%, 100
	}
	
	CheckIfRunning()
	{
		BoundFunc := this.Bound.CheckIfRunning
		SetTimer, %BoundFunc%, Delete
		GuiControl,, % this.hRunButton, &Run ; TODO: Make sure I don't have to specify default GUI
	}
	
	OnMessage(wParam, lParam, Msg, hWnd)
	{
		if (hWnd == this.hCodeEditor)
		{
			; Call BoundFunc after we return and the key press propagates downwards into the edit
			BoundFunc := this.Bound.UpdateStatusBar
			SetTimer, %BoundFunc%, -0
		}
	}
	
	UpdateStatusBar()
	{
		; BoundFunc := this.Bound.UpdateStatusBar
		; SetTimer, %BoundFunc%, Delete
		return
	}
}
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

31 Aug 2015, 12:29

I'm moving to a real repo on GitHub! https://github.com/G33kDude/CodeQuickTester/tree/dev
Single-file versions can be found in the main branch.
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: CodeQuickTester

01 Sep 2015, 04:12

Nice, the app deserves a dedicated repo :D
ABCza on the old forum.
My GitHub.
User avatar
TLM
Posts: 1608
Joined: 01 Oct 2013, 07:52
Contact:

Re: CodeQuickTester

10 Sep 2015, 13:20

FR: 1 click code commenting plz :D
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

05 Oct 2015, 15:12

The main post has been updated with a link to the latest version in the github repo.
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

09 Nov 2015, 08:17

UserScript updated to v0.4.1 (namespace update for new forum domain)
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: CodeQuickTester

04 Aug 2017, 10:18

Sneak peek

Image
User avatar
maestrith
Posts: 825
Joined: 16 Oct 2013, 13:52

Re: CodeQuickTester

04 Aug 2017, 10:35

Scintilla or RichEdit?
John H Wilson III 05/29/51 - 03/01/2020. You will be missed.AHK Studio OSDGUI Creator
Donations
Discord
All code is done on a 64 bit Windows 10 PC Running AutoHotkey x32

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: sanmaodo, Spawnova and 95 guests