Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

PSPad Label Helper - display a list of labels found in PSPad


  • Please log in to reply
40 replies to this topic
evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
This script somewhat makes up for the lack of code-folding in PSPad and adds a few extras - very handy for large scripts which are a pain to navigate.

It's rather like an index for labels and/or functions, hotkeys and directives. You also filter the results (e.g. to find only those labels that contain "gui").

Download:
http://file.autohotk... ... Helper.ahk

robiandi
  • Guests
  • Last active:
  • Joined: --
I like to indent my labels, therefore I changed
If Text%A_Index% contains :
      {
      Colon_Position := InStr(Text%A_Index%, ":")
      StringLeft, Text%A_Index%, Text%A_Index%, %Colon_Position%
      If Text%A_Index% not contains %A_Space%
        {
        StringLen, Text_Length, Text%A_Index%
        If Text_Length !=2 ; avoid junk entries
           LV_Add("", A_Index, Text%A_Index%)
        }
      }
by
If Text%A_Index% contains :
     IfNotInString Text%A_Index%, =                 
      IfNotInString Text%A_Index%, contains       
      {
      Colon_Position := InStr(Text%A_Index%, ":")
      StringLeft, Text%A_Index%, Text%A_Index%, %Colon_Position%
        StringLen, Text_Length, Text%A_Index%
        If Text_Length !=2 ; avoid junk entries
           LV_Add("", A_Index, Text%A_Index%)
      }


evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Glad you managed to follow my code and fix it :lol:

Where you filter:
     IfNotInString Text%A_Index%, =                  
      IfNotInString Text%A_Index%, contains        

I figure "=" filters out ":=" but what is "contains" supposed to filter? EDIT: Never mind, I saw what it was for, when checking if a variable "contains :" :roll:

I'll be uploading a new version shortly with a few other little improvements.

robiandi
  • Guests
  • Last active:
  • Joined: --
It is because otherwise you would get a line like

If Text%A_Index% contains :


in your list.

It is awkward, one has to replace it by the condition that
just the place before ":" must not be %A_SPACE%"

kiu
  • Members
  • 234 posts
  • Last active: Oct 10 2010 07:30 PM
  • Joined: 18 Dec 2005
very usefull script.
Bugs:
retrieves line like these:
1) ; performs an eligible action:
that is a comment
2) Menu, MyContextMenu, Add,Roots,:drive
that is a submenu
3) Gui, 2:Add
that is a gui instruction
that are not labels
I think you could correct it simply by controlling if in the line there are words like ";" Menu" or "Gui" (maybe not only this, I didn't look at the code for now)

Anyway very good script :wink:
____________________
______________________
kiu - www.romeosa.com

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
I think I found a generic way to filter pretty well, just trying to get it to work right at the moment (read: I can't program :lol: )

Also I was thinking about having a choice of what things to display perhaps, but not sure if there are enough useful ones to make it worthwhile (that can be uniquely identified in a straightforward way):
- functions
- find which guis have been used
- possibly variables

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Updated the first post with improved code:
- Should now only find labels (checks if there is a break in A_Space's before the colon - i.e. more than 1 word)
- Changed hotkey to Win+Q (1-handed hotkey for easier use)
- Hotkey hides/shows Gui. Gui closes on selection.
- Tweaked positioning of Gui.

I haven't tried to exclude anything that's commented out. I'm not sure if this would be a good or bad thing since you might still want to find the label. Maybe I'll make it an option if I can.

Further (realistic) suggestions welcome :lol:

kiu
  • Members
  • 234 posts
  • Last active: Oct 10 2010 07:30 PM
  • Joined: 18 Dec 2005
this script is very good, but I've that window and more items are not labels

Posted Image
____________________
______________________
kiu - www.romeosa.com

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Fixed it in the 1st post. Forgot that some people leave out the commas in gui and menu commands (not sure what those weird symbols were, but they only appeared to be in non-label entries anyhow).

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005
Thank you for this wonderful idea.

I played with your code. I was able to simplify it in a lot of cases and I think I made it more robust to find labels. It now also finds functions.

/* 
PSPad Label Helper 
================== 
by evl  www.autohotkey.com/forum/viewtopic.php?t=&p=48986#48986
mod by toralf

Hotkey = F12
  Shows/hides a listview of all labels in the active PSPad window. 
    - Double-click the label name to go to the line in PSPad. 
*/ 

#Persistent 
#SingleInstance force 
Return 

#IfWinActive, ahk_class TfPSPad  
F12:: GoSub, PSPad_Labels_Gui 

PSPad_Labels_Gui: 
  WinGet, PSPadWindowID, ID, A  ;remember PSPadWindow to get back to it 
  Gui, Destroy                  ;destroy old instances
  Fill_ListView()               ;use a function to avoid left-over variables 
Return 

Fill_ListView() { 
    global LsvListOfLabel
    
    ;try # times to get Text from PSPad
    NumberOfTrys = 20
    Loop, {
        SetTitleMatchMode, Slow 
        VarSetCapacity(Text, 1000000) 
        WinGetText, Text, A 
      
        ; trim off junk from the start of the text 
        StringTrimLeft, Text, Text, InStr(Text, "ToolBarProject")  
        StringTrimLeft, Text, Text, InStr(Text, "`n")
        StringTrimLeft, Text, Text, InStr(Text, "`n") 
        StringTrimLeft, Text, Text, InStr(Text, "`n")
      
        ;loop thought Text to find Labels
        ListOfLabels =
        NumberOfLabels = 0
        Loop, Parse, Text, `n ; filter results and add to listview 
          { 
            Line := A_LoopField     ;remove spaces
            If Line contains :,(    ;it may be a subroutine or function
              { 
                Label := CheckForLabel(Line)   ;check if it is a valid label
                If Label {                     ;if it is, store it
                    NumberOfLabels++
                    ListOfIDs%NumberOfLabels%    := A_Index
                    ListOfLabels%NumberOfLabels% := Label
                  }
              } 
          } 
        ;more then one should be found, since there is an entry "C:", that is below the line count of PSPad
        If (NumberOfLabels > 1 )    
            Break
        Else If (A_index = NumberOfTrys){
            MsgBox, 4160, Failed to get Text, Script failed %NumberOfTrys% times to get text from PSPad.
            Return 
          } 
      }
    NumberOfLabels --   ;remove last entry "C:", since it is below the line count of PSPad
    
    ;create GUI
    Gui, +AlwaysOnTop +ToolWindow 
    Gui, Margin, 2, 2 
    Gui, Add, ListView, r%NumberOfLabels% w200 Count%NumberOfLabels% vLsvListOfLabel gLsvListOfLabel, Line|Label 
    Loop, %NumberOfLabels%
        LV_Add("", ListOfIDs%A_Index%, ListOfLabels%A_Index%)
    LV_ModifyCol(1, "AutoHdr Integer") 
    LV_ModifyCol(2) 
  
    ;get GUI ID of still hidden GUI
    DetectHiddenWindows, On 
    Gui, +LastFound
    Gui_ID := WinExist()
  
    ;get width of Columns and adjust width of ListView control
    SendMessage, 0x1000+29, 0, 0, SysListView321, ahk_id %Gui_ID% ; LVM_GETCOLUMNWIDTH is 0x1000+29 
      Width_Column_1 := ErrorLevel 
    SendMessage, 0x1000+29, 1, 0, SysListView321, ahk_id %Gui_ID% ; LVM_GETCOLUMNWIDTH is 0x1000+29 
      Width_Column_2 := ErrorLevel 
    NewWidth := Width_Column_1 + Width_Column_2 + 4
    GuiControl, Move, LsvListOfLabel, w%NewWidth% 

    ;calculate position on right screen edge and show gui
    PosX := A_ScreenWidth - NewWidth - 10
    Gui, Show, AutoSize x%PosX% NoActivate, PSPad Labels 
  } 

CheckForLabel(Line){
    ;find out, if Label is a function or subroutine
    PosColon := InStr(Line, ":")
    PosDoubleColon := InStr(Line, "::")
    PosBraket := InStr(Line, "(")
    If (PosColon > 1 AND PosDoubleColon = PosColon)   ;its a hotkey
        Return
    Else If (PosColon > 1 AND (PosColon < PosBraket OR PosBraket = 0)){
        IsFunction := False
        Pos = %PosColon%
      }
    Else IF (PosBraket > 1 AND (PosBraket < PosColon OR PosColon = 0)){
        IsFunction := True
        Pos = %PosBraket%
      }
    Else             ;this should never happen, but is fail-save
        Return

    ;get the label
    StringLeft, Label, Line, % Pos - 1
    
    ;it is an If statement "If("
    If (Label = "If")
        Return

    ;check each char in Label if it is allowed
    Loop, Parse, Label
        If ( A_LoopField <> "_" )
            If A_LoopField is not Alnum
                Return
    ;add postfix    
    If Label {
        If IsFunction
            Return Label "()"
        Else
            Return Label ":"
      }
  }

LsvListOfLabel: 
  If (A_GuiEvent = "DoubleClick") { 
       LV_GetText(Row_Number, A_EventInfo)  ; Get the row's first-column text. 
       Gui, Destroy 
       WinActivate, ahk_id %PSPadWindowID% 
       Send, ^g%Row_Number%{Enter} 
    } 
Return 

GuiClose:  ; Indicate that the script should exit automatically when the window is closed. 
GuiEscape: 
    Gui, Destroy 
Return 

Ciao
toralf
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.

robiandi
  • Guests
  • Last active:
  • Joined: --
@toralf:

but in your version you cann't indent the labels.

To obtain this you must omit in the function CheckForLabel(Line) the part
Loop, Parse, Label
        If ( A_LoopField <> "_" )
            If A_LoopField is not Alnum
                Return
But now at the very beginning of this function you have to put some conditions as for example
IfInString line,:=  
         return


robiandi
  • Guests
  • Last active:
  • Joined: --

But now at the very beginning of this function you have to put some conditions as for example

IfInString line,:=  
         return

It is surely not as easy as here presented but in my example it just worked.

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005

but in your version you cann't indent the labels.

Dear robiandi,
Could you please clarify what you want to indent?
Are your labels indented in the code, or do you want to have the lables indented in the ListView?

In the furture I will extend the code to also show hotkeys and directives.
With 4 checkboxes one can limit the list.

A limitation currently exist e.g. if a function is somewhere called without a return value, it will be in the list. I will extend the code, that at least the AHK internal function will not show up.
Ciao
toralf
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.

kiu
  • Members
  • 234 posts
  • Last active: Oct 10 2010 07:30 PM
  • Joined: 18 Dec 2005
For toralf:
with your code, at the end of the list I get some items like these

Line Label
245 E:
247 C:
259 C:

and my source code is only 242 lines lenght.
Sometimes I get only these items and not the real labels.
____________________
______________________
kiu - www.romeosa.com

robiandi
  • Guests
  • Last active:
  • Joined: --
@toralf:

Dear robiandi,
Could you please clarify what you want to indent?
Are your labels indented in the code, or do you want to have the lables indented in the ListView?

They are indented in the code, that means instead of for example
#p::
...
here comes the ahk-code
I prefer
#p::
...
here comes the ahk-code

The same way I would like to indent the head of the functions.