 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Rabiator
Joined: 17 Apr 2005 Posts: 266 Location: Sauerland
|
Posted: Sat Jan 27, 2007 8:26 pm Post subject: AHK code explorer for PSPad |
|
|
AHK Code Explorer
PSPad (my favourite editor) has a feature called code explorer, supporting several programming languages.
With it you can see and navigate to functions, defines, labels etc.
Due to the lack of a code explorer for AutoHotkey I coded something similar to bridgeover the time till PSPad supports it.
(Jan 29, 2007: Meanwhile AutoHotkey is supported, but still very rudimentarily.)
It is easy to use:
You start it and switch to the PSPad window.
With ctrl-shift-e you display the code explorer window with a treeview.
If you select an element (hotkey, hotstring, label or function) with a double-click, the code explorer window will disappear and you will be navigated to the corresponding line in the source code.
Or you hide the window with a second ctrl-shift-e.
The AHK code explorer considers both types of comments. It is surely adaptable to other editors; I pointed out the PSPad specific actions.
Changes
Jan 31, 2007: added a user definable label type.
Feb 12, 2007: advanced the above to show comments in a hierarchical contents list. The identification pattern has changed.
Mar 31, 2007: Fixed: Hotstrings with options will be identified now correctly. Fixed: Assignments like var:=value starting at the beginning of a line won't be identified as labels any more.
Comment format
A hierarchical contents list is fed with comment lines with certain rules.
Due to affect the readability of existing comments as little as possible, the precursory pattern for hierarchical comment lines is ";.", with eventually directly following points.
Because most coders start their comments in the same indentation as the following code, the HCL doesn't have to start necessarily in the first column. But the ";." sequence must be the first printable characters in the line.
The number of points in the precursory pattern represents the corresponding level inside the TreeView. ";." is the highest level, ";.." the second level etc. The level is not limited. | Code: | ;. Headline 1
;.. Headline 1.1
;.. Headline 1.2
;... Headline 1.2.1
;. Headline 2 |
To avoid the necessity of creating additional lines with hierarchical comments, it is possible to show only a part of a comment line. AHK code explorer uses a separator consisting of a multiple-space/tab sequence, a succession of two or more spaces/tabs. That still allows largely individual formatting. Which text will be displayed obeys the following rules:
a) No separator: the complete line
b) One separator: the text followed by the separator.
c) Two ore more separators: the first text enclosed by two separators
A multiple-space/tab sequence following the precursory pattern or standing at the end of the line will not be identified as a separator.
| Code: | ;. The complete line will be shown in the TreeView.
;. as well as this line, without leading spaces within the comment
;. as well as this line
;. visible hidden
;. hidden visible hidden hidden hidden
;. visible hidden
|
Hierarchical comment lines are also recognized inside /* ... */-type comments.
Indentation
If the indentation level raises by more than 1, additional empty labels will be inserted in the TreeView.
This script itself is commented in the described style.
| Code: | ; A simplified surrogate for the missing PSPad code explorer for AutoHotkey
; by Rabiator
; -------------------------------------------------------------------------
;. --- Groups ---
; Control existance, order and behavior of the groups. The following table
; contains for each group its name, starting state of "Expand" and an icon
; number. If you dont't want to have it displayed in the TreeView, remove it
; from the table.
;.. The Group names are: "Functions", "Hotkeys", "Hotstrings", "Labels",
; "DllCalls", "MyLabels". These names are fix.
;.. Expanded : 0 = collapsed, 1 = expanded
;.. Icon number : The 3rd element is the number of the icon in the ImageList
; (see there).
Groups =
(
Functions, 0, 2
Hotkeys, 0, 3
Hotstrings, 0, 4
Labels, 0, 5
DllCalls, 0, 6
MyLabels, 1, 7
)
Loop, Parse, Groups, `n
{
Sep := (A_Index = 1) ? "" : "|"
StringSplit, Arr, A_LoopField, `,
GroupNames = %GroupNames%%Sep%%Arr1%
%Arr1%__Expanded = %Arr2%
%Arr1%__IconNo = %Arr3%
}
New := 1
; Start and Stop
^+e::
If (New = 0)
{
Gui, Destroy
New := 1
Return
}
; Only run if the editor window is active.
IfWinNotActive, PSPad -
Return
New := 0
;. Get the actual line number
; (PSPad: from the status bar. I hope this won't change in later versions.)
My_TitleMatchMode := A_TitleMatchMode
My_TitleMatchModeSpeed := A_TitleMatchModeSpeed
SetTitleMatchMode, 2
SetTitleMatchMode, Slow
WinGetText, Var
RegExMatch(Var, "s)\s+?(?'LineNo'[\d]+) :\s*\d+\s*\((?'Lines'\d+)", Act)
SetTitleMatchMode, %My_TitleMatchMode%
SetTitleMatchMode, %My_TitleMatchModeSpeed%
;. Save the contents
MyClipboard := ClipBoard
Send, ^a^c
Sleep, 100
Contents := Clipboard
Clipboard := MyClipboard
; Unselect the text by jumping to the actual line number (PSPad).
Send, ^g%ActLineNo%{ENTER}
; ------------------------------------------------------------------------
;. Parse for hotstrings, hotkeys, labels, functions and DllCalls
; Clear all lists
HotKeys =
Hotstrings =
Labels =
Functions =
DllCalls =
MyPatterns =
MyLabels =
bComment := 0
bFunction := 0
;. Parse each line
Loop, Parse, Contents, `n, `r
{
LineNo := A_Index
Line := A_LoopField
;
If (Mod(LineNo, 1000) = 0)
ToolTip Parsing line %LineNo% of %ActLines% , A_ScreenWidth/2, A_ScreenHeight/2
;.. Exclude /* .. */ comments
FoundPos := RegExMatch(Line, "^\s\/\*")
If (FoundPos)
{
bComment := 1 ; a comment section begins
Continue
}
If (bComment = 1)
{
FoundPos := RegExMatch(Line, "^\s\*\/")
If (FoundPos)
bComment := 0 ; a comment section ends
Continue
}
;.. Find Hotkeys
FoundPos := RegExMatch(Line, "([^\s:]+?)::", HotkeyPat)
If (FoundPos = 1)
Hotkeys = %Hotkeys%%HotkeyPat1%,%LineNo%`n
;.. Find Hotstrings
; improved by bold
FoundPos := RegExMatch(Line, ":[*?a-zA-Z0-9]*:([^\s:]+?)::", HotstringPat)
If (FoundPos)
Hotstrings = %Hotstrings%%HotstringPat1%,%LineNo%`n
;.. Find Labels
FoundPos := RegExMatch(Line, "([^\s;:]+):(\s|$)", LabelPat)
If (FoundPos = 1)
Labels = %Labels%%LabelPat1%,%A_Index%`n
;.. Find Functions
If (bFunction = 0)
{
; alphanumeric letters (international) and # _ @ $ ? [ ]
FoundPos := RegExMatch(Line, "^\s*(?'Name'[\w€-ÿ#_@$\?\[\]]+)(?'Pars'\(.*\))", Function)
If (FoundPos)
{
; prevent from taking an expression-if with directly following ( as a function.
If (FunctionName = "if")
Continue
FuncDeclLine := LineNo
; Find the {
; OTB?
FoundPos := RegExMatch(Line, ")\s*\{")
If (FoundPos)
; { found in the 1st line
Functions = %Functions%%FunctionName%%FunctionPars%,%FuncDeclLine%`n
Else
bFunction := 1
}
}
Else
{
; no OTB
FoundPos := RegExMatch(Line, "^\s*{")
If (FoundPos)
{
; { found in one of the following lines
Functions = %Functions%%FunctionName%%FunctionPars%,%FuncDeclLine%`n
bFunction := 0
}
FoundPos := RegExMatch(Line, "^\s*?[^;\s]")
If (FoundPos)
; found something that doesn't belong to a function
bFunction := 0
}
;.. Find DllCalls
FoundPos := RegExMatch(Line, "^\s*(DllCall\(.*?\))", DllCallPat)
If (FoundPos)
DllCalls = %DllCalls%%DllCallPat1%,%LineNo%`n
;.. Find user-defined labels
If GroupNames contains MyLabels
{
; Search for the pattern ";."
FoundPos := RegExMatch(Line, "^\s*;(\.+)\s(.*)", MyPat)
If (FoundPos)
{
Line = %Line% ; Trim spaces and tabs
; Evaluate the indentation level
StringLen Level, MyPat1
MyPat2 = %MyPat2% ; Trim spaces and tabs
Var := RegExReplace(MyPat2, "\s{2,}", "¢")
StringSplit, Arr, Var, ¢
If (Arr0 > 2)
MyLabels = %MyLabels%%Level%|%Arr2%,%LineNo%`n
Else
MyLabels = %MyLabels%%Level%|%Arr1%,%LineNo%`n
}
}
}
; ------------------------------------------------------------------------
;. Prepare and create the GUI
;.. Create an ImageList
ImageListID := IL_Create(7)
IL_Add(ImageListID, "shell32.dll", 4)
IL_Add(ImageListID, "shell32.dll", 42)
IL_Add(ImageListID, "shell32.dll", 13)
IL_Add(ImageListID, "shell32.dll", 29)
IL_Add(ImageListID, "shell32.dll", 44)
IL_Add(ImageListID, "shell32.dll", 45)
IL_Add(ImageListID, "shell32.dll", 46)
;.. Create the GUI
Gui, Add, TreeView, ImageList%ImageListID% R20 gJump w400 h500 vTV
;.. Delete pending `n, sort objects and create the treeview
Level := -1
Loop, Parse, GroupNames, |
{
Group := A_LoopField
ObjIndex := A_Index
IconNo := A_Index + 1
StringTrimRight, %Group%, %Group%, 1
; Treat MyLabels differently
If (Group <> "MyLabels")
{
Sort, %Group%
ID_%Group% := TV_Add(Group, 0, "Icon1 Bold Expand" . %Group%__Expanded)
StringSplit, Arr%Group%, %Group%, `n
Loop, % Arr%Group%0
{
RegExMatch(Arr%Group%%A_Index%, "(.*),(\d*)", Name)
ID_%Group%C%A_Index% := TV_Add(Name1, ID_%Group%, "Icon" . %Group%__IconNo gJump)
a := ID_%Group%C%A_Index%
Line_%a% := Name2
}
}
Else ; Group is "MyLabels"
{
If (Level = -1) {
Level := 0
; Create the item and save the last ItemID of this level.
LevelID%Level% := TV_Add(Group, 0, "Icon1 Bold Expand" . %Group%__Expanded)
LastItem := LevelID%Level%
}
; Add all items regarding their level.
StringSplit, Arr%Group%, %Group%, `n
Loop, % Arr%Group%0
{
RegExMatch(Arr%Group%%A_Index%, "(.*),(\d*)", Name)
RegExMatch(Name1, "(\d+)\|(.*)", SubName)
NewLevel := SubName1
Name := SubName2
LineNo := Name2
Loop
{
If (NewLevel <= Level + 1)
; max. 1 indent
{
ParentLevel := NewLevel - 1
LevelID%NewLevel% := TV_Add(Name, LevelID%ParentLevel%, "Expand Icon7" . gJump)
If (NewLevel > Level)
; Mark parent item with bold and folder icon
TV_Modify(LevelID%ParentLevel%, "Bold Icon1")
Level := NewLevel
a := LevelID%NewLevel%
Line_%a% := LineNo
Break
}
Else
; Overall more than 1 indent
; Step-by-step we create and add an indented empty item.
{
Level++
ParentLevel := Level - 1
LevelID%Level% := a := TV_Add("<empty>", LevelID%ParentLevel%, "Expand Icon7" . gJump)
Line_%a% := -1 ; Empty items don't have a valid line number.
}
}
}
}
}
ToolTip
Gui, +Resize
Gui, Show,
Return
GuiSize:
; The treeview gets automatically resized with the window.
GuiControl, Move, TV, % "h" A_GuiHeight-20 " w" A_GuiWidth-20
; Minimizing the window will destroy it.
If (A_EventInfo = 1)
{
Gui, Destroy
New := 1
}
Return
GuiClose:
ExitApp
; Jump to the line with the selected item.
Jump:
; It's impossible to jump to the category
ItemID := TV_GetSelection()
ParentID := TV_GetParent(ItemID)
If Not ParentID
Return
; Fetch the line number
LineNo := Line_%ItemID%
; Don't jump to an empty item
If (LineNo = -1)
Return
Gui, Submit
; A command that selects the found line (PSPad).
Send, ^g%LineNo%{ENTER}
; Remove the GUI
Gui, Destroy
New := 1
Return |
__________________________________________
Created with BBCodeWriter 6.6 - the one and only 
Last edited by Rabiator on Fri Mar 30, 2007 11:47 pm; edited 4 times in total |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Sun Jan 28, 2007 11:16 am Post subject: |
|
|
Hi Rabiator,
Thanks for sharing.
Could you please point out what the differences are to ActiveGoTo? Thanks. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
Rabiator
Joined: 17 Apr 2005 Posts: 266 Location: Sauerland
|
Posted: Sun Jan 28, 2007 3:53 pm Post subject: |
|
|
| toralf wrote: | | Could you please point out what the differences are to ActiveGoTo? Thanks. | I conceive suspicion that this is a rethorical question .
Indeed, after discovering ActiveGoto's actual state I didn't feel certain whether to release my script or not.
My goal was to have a tool working similarly to PSPad code explorer in usage and appearance (especially the treeview) - ActiveGoto is not, so I released mine.
That is the main difference.
If the question was not rethorical:
ActiveGoto is more universal and configurable (and coded by exceptionally gifted programmers ), displays only one type of items in a single list. AHK Code Explorer (now it has a name) is more special, doesn't need to be configured due to its mission and displays all items sorted by type.
__________________________________________
Created with BBCodeWriter 6.6 - the one and only  |
|
| Back to top |
|
 |
skwire
Joined: 18 Jan 2006 Posts: 150 Location: Conway, Arkansas
|
Posted: Mon Jan 29, 2007 7:29 am Post subject: Re: AHK code explorer for PSPad |
|
|
| Rabiator wrote: | | Due to the lack of a code explorer for AutoHotkey I coded something similar to bridgeover the time till PSPad supports it. |
It's supported now in the latest beta.
http://pspad.cincura.net/beta/
Specifically:
http://pspad.cincura.net/beta/pspad453b2253.cab
It's not perfect...but it's a start. |
|
| Back to top |
|
 |
Guest
|
Posted: Mon Jan 29, 2007 11:21 pm Post subject: Re: AHK code explorer for PSPad |
|
|
| skwire wrote: | | It's supported now in the latest beta. | Thank you for the hint! I tried it out.
| Quote: | | It's not perfect...but it's a start. | Like mine.
It's a nice idea to show the DllCalls, I'll update my script with this ability.
__________________________________________
Created with BBCodeWriter 6.6 - the one and only  |
|
| Back to top |
|
 |
kiu
Joined: 18 Dec 2005 Posts: 229 Location: Italy - Galatro(RC)
|
Posted: Tue Jan 30, 2007 3:51 pm Post subject: |
|
|
Very good!
Only 1 problem: the script show if(..) as functions.
As very simple workaround:
| Code: |
if(SubStr(Name, 1, 2)="If")
continue
|
after line 165 _________________ ____________________
______________________
kiu |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3842 Location: Bremen, Germany
|
Posted: Tue Jan 30, 2007 9:03 pm Post subject: |
|
|
| Rabiator wrote: | | If the question was not rethorical | It wasn't. I am currently just to busy to test scripts, and I wanted to get an idea of what this script does differently. Thanks for pointing it out. I will test it if time permints. Thank you for sharing. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
kiu as guest Guest
|
Posted: Tue Jan 30, 2007 11:13 pm Post subject: |
|
|
the main difference that I like is the grouping of items by category in e treeview:
+function
+---function1()
+---function2()
+---function3()
+hotkeys
+---hotkey1
...
so you can find faster what you want. I think it will be good to have the best from all two scripts in the same one. |
|
| Back to top |
|
 |
daonlyfreez
Joined: 16 Mar 2005 Posts: 745 Location: Berlin
|
Posted: Wed Jan 31, 2007 12:14 am Post subject: |
|
|
Nice!
Some quick mods...
| Code: | 145 ; Create the GUI
146 Gui, Add, TreeView, ImageList%ImageListID% R20 gJump w400 h500 vTV
158 ID_%Group% := TV_Add(Group, 0, "Icon1 Bold Expand")
169+
Gui, +Resize
Gui, Show,
Return
GuiSize:
GuiControl, Move, TV, % "h" A_GuiHeight-20 " w" A_GuiWidth-20
Return
GuiClose:
ExitApp |
_________________ (sorry, homesite offline atm) |
|
| Back to top |
|
 |
Rabiator
Joined: 17 Apr 2005 Posts: 266 Location: Sauerland
|
Posted: Wed Jan 31, 2007 11:45 pm Post subject: |
|
|
| kiu wrote: | | Only 1 problem: the script show if(..) as functions. | Thanks for your suggestion! The if "function" is now skipped.
| daonlyfreez wrote: | Some quick mods...  | I added your quick mods, thank you!
I also added a user definable label type. It lets us navigate to important/interesting script passages like explanations, structures, sections etc. that don't belong to the previous types. (Of course that is an extension to the original code explorer functions and exceeds my primary intention, but: who cares?)
Example:
| Code: | ; ---------------------
;@ List of used hotkeys
;
; F1 = ...
; F2 = ... |
The AHK code explorer in this example searches for the pattern ";@" at the beginning of a line and displays in the new group "MyLabels" for every matching line the text that follows the found pattern.
You can define the pattern in section "User-defined labels", (at the moment line 16); if you don't want this feature, leave the string empty.
A glance into a possible future: several or/and even nested label types (= more levels in the treeview), which allow you to give big (and therefore perhaps confusing) scripts a helpful structure (at least for editing ).
__________________________________________
Created with BBCodeWriter 6.6 - the one and only  |
|
| Back to top |
|
 |
Rabiator
Joined: 17 Apr 2005 Posts: 266 Location: Sauerland
|
Posted: Mon Feb 12, 2007 10:36 pm Post subject: |
|
|
Added: "hierarchical" comment lines to support a structured contents list, see the first post.
__________________________________________
Created with BBCodeWriter 6.6 - the one and only  |
|
| Back to top |
|
 |
bold
Joined: 20 Apr 2006 Posts: 15
|
Posted: Fri Mar 30, 2007 5:26 pm Post subject: |
|
|
Nice,
I changed the hotstring regex because not all hotstrings are found
| Code: | ;.. Find Hotstrings
FoundPos := RegExMatch(Line, ":[*?a-zA-Z0-9]*:([^\s:]+?)::", HotstringPat)
If (FoundPos)
Hotstrings = %Hotstrings%%HotstringPat1%,%LineNo%`n
|
|
|
| Back to top |
|
 |
Guest+ Guest
|
Posted: Fri Mar 30, 2007 8:30 pm Post subject: |
|
|
I tried it on only one script (poorely written by me but works) and :
It didn't find any functions
it recognized xx:=xxx as a label |
|
| Back to top |
|
 |
Guest+ Guest
|
Posted: Fri Mar 30, 2007 8:33 pm Post subject: |
|
|
| rajat's script works perfectly on the same script |
|
| Back to top |
|
 |
Rabiator
Joined: 17 Apr 2005 Posts: 266 Location: Sauerland
|
Posted: Fri Mar 30, 2007 11:48 pm Post subject: |
|
|
@bold
Thanks for your report and improvement! I adopted it.
@Guest+
It is fixed now, thanks for your report.
__________________________________________
Created with BBCodeWriter 6.6 - the one and only  |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|