V1.2 - added full window height and dark mode option
V1.3 - added additonal labels 0-9 (modify #CharactersAboveNumbers to your needs)
V1.4 - added color for comments, tooltips
V1.5 - added non quiting mode (see options below)
Code: Select all
; Define
; Jump to Marker V1.5 by Michael Vogel
; ------------------------------------
; Example for Tool Settings:
; --------------------------
; Command Line: %COMPILEFILE\..\..\Pure\Tools\Tool Marker.exe
; Arguments: "%TEMPFILE" 110552 "JetBrains Mono Semibold" the second parameters number configures all options*
; Working Dir.: %COMPILEFILE\..\..\Pure\Tools
; Name: &Jump to Marker...
; Event Trigger: Menu Or Shortcut Should be 'or' not 'Or' (the IDE should get a better 'Undo'...;)
; Shortcut: Ctrl + J
; Options:
; X----- 1: allows jumping to a marker without quitting the tool (space key, left click)
; -X---- 1: dark mode
; --X--- 1: full window height
; ---X-- 0-9: window width
; ----X- 0: hide line column, 1-9 set column width
; -----X 0-9: font size
#CharactersAboveNumbers= "=!"+#DOUBLEQUOTE$+"§$%&/()"; characters above keyboard numbers 0 .. 9
#MarkerTooltipLines= 6; additional code lines shown in tooltip (hold control key)
#MarkerTooltipLineLength= 50; maximum code line characters in tooltips
#MarkerToolDefaults= 111221; 11402
#MarkerToolFont= "JetBrains Mono Medium"
EnableExplicit
#ToolExe= 1*Bool(#PB_Compiler_Debugger=#Null); Compiled Tool Exe
#BufferLines= 250
#DpiBits= 12+SizeOf(Integer)
#DpiScale= 1<<#DpiBits
Enumeration
#File
#True
#Bingo
EndEnumeration
Enumeration
#Text
#Text_
#Text0
#Line
#Line_
#Proc
#Proc_
#Maco
#Maco_
#High
#High_
#BackColorEnd
EndEnumeration
Enumeration
#Win
#Lst
#Fnt
#KeyGo
#KeySync
#KeyExit
EndEnumeration
Structure LongType
Low.l
High.l
EndStructure
Structure ResultType
StructureUnion
Quad.q
Long.LongType
EndStructureUnion
EndStructure
Structure SourceType
Code.s
PLine.i
Highlight.i
Null.i
EndStructure
Structure ToolType
Lines.i
Asize.i
Oflag.i
Pline.i
Width.i
Lsize.i
DpiScale.i
FontSize.i
FontName.s
Marker.s
SourceFile.s
DarkMode.i
JumpMode.i
Color.i[#BackColorEnd]
EndStructure
Structure IdeType
HandleIde.i
HandleScintilla.i
Cursor.i
ClassTextIde.s
TitleTextIde.s
EndStructure
Global Ide.IdeType
Global Tool.ToolType
Global Dim Source.SourceType(Tool\Asize)
Ide\ClassTextIde= "WindowClass_2"
Ide\TitleTextIde= "PureBasic"
; EndDefine
Macro ScaleUp(value)
(((value)*Tool\DpiScale)/#DpiScale)
EndMacro
Macro ScaleDown(value)
(((value)*#DpiScale)/Tool\DpiScale)
EndMacro
: CompilerIf #ToolExe=#Null :
Procedure.i SearchIdeHandle(hwnd.i)
Protected ClassText.s=Space(256)
With Ide
If hwnd
GetClassName_(hwnd,@classText,256)
If classText=\ClassTextIde
GetWindowText_(hwnd,@classText,256)
If Not Asc(\TitleTextIde) Or FindString(classText,\TitleTextIde)
\HandleIde=hwnd
ProcedureReturn 0
EndIf
EndIf
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndWith
EndProcedure
Procedure.i SearchScintilla(hwnd.i)
Protected ClassText.s=Space(256)
With Ide
If hwnd
GetClassName_(hwnd,@classText,256)
If classText="Scintilla"
\HandleScintilla=hwnd
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndWith
EndProcedure
: CompilerEndIf :
Procedure ToolTip(title.s,tip.s)
Static TooltipHandle
Protected Info.TOOLINFO
EnumerationBinary
#ToolTipMask= %0000000111
#ToolTipTypeStandard= %0000000000
#ToolTipTypeBalloon= %0000000001
#ToolTipAlignmentStandard= %0000000000
#ToolTipAlignmentCenter= %0000010000
#ToolIconNone= %0000000000
#ToolIconInfo= %0100000000
#ToolIconWarning= %1000000000
#ToolIconError= %1100000000
EndEnumeration
#TTS_ALWAYSTIP= $1
#TooltipMode= #ToolIconInfo|#ToolTipTypeStandard|#ToolTipAlignmentStandard
title+Space(32)
If TooltipHandle
With Info
\cbSize= SizeOf(TOOLINFO)
\hWnd= WindowID(#Win)
\uId= GadgetID(#Lst)
\lpszText= @tip
EndWith
SendMessage_(TooltipHandle,#TTM_SETDELAYTIME,#TTDT_RESHOW,1000); ?
SendMessage_(TooltipHandle,#TTM_SETTITLE,(#ToolIconInfo|#ToolTipTypeStandard|#ToolTipAlignmentStandard)>>8&#ToolTipMask,@title)
SendMessage_(TooltipHandle,#TTM_UPDATETIPTEXT,0,Info)
Else
TooltipHandle=CreateWindowEx_(0,"toolTips_class32","",#WS_POPUP | (#TTS_BALLOON *(#TooltipMode&#ToolTipMask)) | #TTS_NOPREFIX,0,0,0,0,0,0,0,0)
SetWindowPos_(TooltipHandle,#HWND_TOPMOST,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOACTIVATE)
Info\cbSize= SizeOf(TOOLINFO)
Info\uFlags= #TTF_IDISHWND | #TTF_SUBCLASS | (#TTF_CENTERTIP * (#TooltipMode>>4)&#ToolTipMask)
Info\hWnd= WindowID(#Win)
Info\uId= GadgetID(#Lst)
Info\hInst= 0
Info\lpszText= @tip
SetWindowTheme_(TooltipHandle,#Empty$,#Empty$); [*]
SendMessage_(TooltipHandle,#TTM_SETTIPTEXTCOLOR,Tool\Color[#Text],0); [*]
SendMessage_(TooltipHandle,#TTM_SETTIPBKCOLOR,Tool\Color[#Line_],0); [*]
SendMessage_(TooltipHandle,#TTM_SETDELAYTIME,#TTDT_INITIAL,1000)
SendMessage_(TooltipHandle,#TTM_SETDELAYTIME,#TTDT_AUTOPOP,15000)
SendMessage_(TooltipHandle,#TTM_SETMAXTIPWIDTH,0,400)
SendMessage_(TooltipHandle,#TTM_SETTITLE,(#TooltipMode>>8)&#ToolTipMask,title)
SendMessage_(TooltipHandle,#TTM_ADDTOOL,0,Info)
EndIf
EndProcedure
Procedure.q MyTrim(*s.Character)
Protected p,l,r,m
Repeat
p+1
Select *s\c
Case #Null
ProcedureReturn r<<32+l+1
Case ' ',#TAB
If m=#Null
l=p
EndIf
Default
r=p
If m=#Null
m=#True
EndIf
EndSelect
*s+SizeOf(Character)
ForEver
EndProcedure
Procedure Jump(marker,mode)
Protected line
Protected Count
If mode Or Tool\JumpMode
If GetKeyState_(#VK_SHIFT)&128
line=GetGadgetItemData(#Lst,marker)
EndIf
If line=0
line=Val(GetGadgetItemText(#Lst,marker,1))
EndIf
With Ide
If \HandleIde
SendMessage_(\HandleScintilla,#SCI_ENSUREVISIBLE,line - 1, 0)
SendMessage_(\HandleScintilla,#SCI_GOTOLINE,line - 1, 0)
Count=SendMessage_(\HandleScintilla,#SCI_LINESONSCREEN, 0, 0) / 2
SendMessage_(\HandleScintilla, #SCI_SCROLLCARET, line - 1, 0)
If Abs(\Cursor - line) < Count
Count=0
ElseIf \Cursor > line
Count=-Count
EndIf
SendMessage_(\HandleScintilla, #SCI_LINESCROLL, 0, Count)
EndIf
If mode
SetForegroundWindow_(\HandleIde)
SetActiveWindow_(\HandleIde)
EndIf
EndWith
If mode
End
EndIf
EndIf
EndProcedure
Procedure ResizeWindows(h,m,w,l)
If m=#WM_SIZING
ResizeGadget(#Lst,#PB_Ignore,#PB_Ignore,WindowWidth(#Win),#PB_Ignore)
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure Main()
Protected a,c,h,i,m,n,p,v,w
Protected r.ResultType
Protected s.s,t.s
Protected rect.Rect
Protected dot.Point
Protected Info.LVHITTESTINFO
With Ide
CompilerIf #ToolExe
Ide\HandleIde=Val(GetEnvironmentVariable("PB_TOOL_MainWindow"))
Ide\HandleScintilla=Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
CompilerElse
EnumChildWindows_(0,@SearchIdeHandle(),0)
EnumChildWindows_(\HandleIde,@SearchScintilla(),0)
CompilerEndIf
If \HandleIde
\Cursor=SendMessage_(\HandleScintilla,#SCI_GETCURRENTPOS, 0, 0)
\Cursor=SendMessage_(\HandleScintilla,#SCI_LINEFROMPOSITION, \Cursor, 0)
EndIf
EndWith
With Tool
CompilerIf #PB_Compiler_Debugger
\SourceFile="C:\Tools\Garmin\Connect\Information\Pure\Screeny.pb"
\SourceFile="C:\Tools\Programmer\Pure\Tools\Tools\Tool Marker.pb"
CompilerElse
\SourceFile=ProgramParameter(0)
CompilerEndIf
s=ProgramParameter(1)
If s
n=Val(s)
Else
n=#MarkerToolDefaults
EndIf
\JumpMode=Bool(n>99999); Default (0): disable space and left click
n%100000
\DarkMode=Bool(n>9999); Default (0): light mode
n%10000
If \DarkMode
\Color[#Text]= $CCCCCC
\Color[#Text_]= $AFFFFF
\Color[#Text0]= $888888
\Color[#Line]= $3F3F3F
\Color[#Line_]= $333333
\Color[#Proc]= $102050
\Color[#Proc_]= $001040
\Color[#Maco]= $603828
\Color[#Maco_]= $502818
\Color[#High]= $181828
\Color[#High_]= $000000
Else
\Color[#Text]= #Black
\Color[#Text_]= $200000
\Color[#Text0]= $888888
\Color[#Line]= $E8FFF8
\Color[#Line_]= $E0FAF0
\Color[#Proc]= $E0F8FF
\Color[#Proc_]= $DAF0F9
\Color[#Maco]= $FFF8E0
\Color[#Maco_]= $F9F0DA
\Color[#High]= $A8FAE0
\Color[#High_]= $90EFD0
EndIf
v=Bool(n>999); Default (0): full screen height
n%1000
\Width=250+(n/100)*100; Window width
\Lsize=(n%100)/10; Line column width
If \Lsize
\Lsize+4
EndIf
n%10; Font size
n%10-5
\FontSize=12+n<<Bool(n>0); 7, 8, 9, 10, 11, 12, 14, 16, 18, 20
\FontName=ProgramParameter(2); Font name
If \FontName=""
\FontName=#MarkerToolFont; "JetBrains Mono Semibold"
EndIf
If ReadFile(#File,\SourceFile,#PB_File_SharedRead)
While Eof(#File)=#Null
\Lines+1
If \Lines>\Asize
\Asize+#BufferLines
ReDim Source(\Asize)
EndIf
s=ReadString(#File)
r\Quad=MyTrim(@s)
s=Mid(s,r\Long\Low,r\Long\High-r\Long\Low+1)
If Left(s,9)="Procedure" Or Left(s,6)="Macro "
\Pline=\Lines
EndIf
Source(\Lines)\Code=s
Source(\Lines)\PLine=\Pline
If s=""
Source(\Lines)\Null=#True
ElseIf PeekC(@s)=';'
If \Oflag=#True
If Left(s,9)="; Markers"
\Marker=StringField(s,2,"=")
\Oflag=#Bingo
EndIf
ElseIf Left(s,20)="; IDE Options = Pure"
\Oflag=#True
Else; If Left(s,5)="; /!\"
Source(\Lines)\Highlight=#True
EndIf
EndIf
Wend
CloseFile(#File)
\DpiScale=GetDeviceCaps_(GetDC_(0),#LOGPIXELSX)<<#DpiBits/96
If \Oflag=#Bingo
w=ScaleDown(GetSystemMetrics_(#SM_CYFULLSCREEN))-5; ?
LoadFont(#Fnt,\FontName,\FontSize)
OpenWindow(#Win,ScaleDown(GetSystemMetrics_(#SM_CXFULLSCREEN))-\Width,0,0,0,"Jump to Marker...",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_Invisible)
SetWindowColor(#Win,\Color[#Line])
WindowBounds(0,\Width,w,\Width,w)
SetGadgetFont(#PB_Any,FontID(#Fnt))
ListIconGadget(#Lst,0,0,\Width,w,"#",25,#PB_ListIcon_FullRowSelect)
SetGadgetColor(#Lst,#PB_Gadget_FrontColor,\Color[#Text])
SetGadgetColor(#Lst,#PB_Gadget_BackColor,\Color[#Line])
AddGadgetColumn(#Lst,1,"Line",\FontSize*\Lsize*2/3)
AddGadgetColumn(#Lst,2,"Procedure/Macro",120+\Width/25)
AddGadgetColumn(#Lst,3,"Source Code",1000)
Protected lvm.LV_COLUMN
lvm\mask=#LVCF_FMT
lvm\fmt=#LVCFMT_CENTER
SendMessage_(GadgetID(#Lst),#LVM_SETCOLUMN,0,@lvm)
lvm\fmt=#LVCFMT_RIGHT
SendMessage_(GadgetID(#Lst),#LVM_SETCOLUMN,1,@lvm)
AddKeyboardShortcut(#Win,#PB_Shortcut_Escape,#KeyExit)
AddKeyboardShortcut(#Win,#PB_Shortcut_Space,#KeySync)
AddKeyboardShortcut(#Win,#PB_Shortcut_Space|#PB_Shortcut_Shift,#KeySync)
AddKeyboardShortcut(#Win,#PB_Shortcut_Return|#PB_Shortcut_Shift,#KeyGo)
AddKeyboardShortcut(#Win,#PB_Shortcut_Return,#KeyGo)
\Asize=CountString(\Marker,",")+1
For i=1 To \Asize
n=Val(StringField(\Marker,i,","))
If n
If Ide\Cursor>=n
a=i
EndIf
p=Source(n)\PLine
If p
s=StringField(Source(p)\Code,2," ")
Else
s="-"
EndIf
If m<26
t=Chr('A'+m)
ElseIf m<36
t=Chr(22+m)
Else
t="-"
EndIf
AddGadgetItem(#Lst,m,t+#LF$+Str(n)+#LF$+s+#LF$+Source(n)\Code)
SetGadgetItemData(#Lst,m,p)
If Source(n)\Highlight
SetGadgetItemColor(#Lst,m,#PB_Gadget_BackColor,\Color[#High+m&1])
SetGadgetItemColor(#Lst,m,#PB_Gadget_FrontColor,\Color[#Text_])
Else
If m&1
SetGadgetItemColor(#Lst,m,#PB_Gadget_BackColor,\Color[#Line_])
EndIf
If Source(n)\Null
t="- Empty line"
If \Lsize=0
t+" "+Str(n)
EndIf
SetGadgetItemText(#Lst,m,t+" -",3)
SetGadgetItemColor(#Lst,m,#PB_Gadget_FrontColor,\Color[#Text0],3)
EndIf
EndIf
SetGadgetItemColor(#Lst,m,#PB_Gadget_BackColor,\Color[#Proc+Bool(PeekC(@s)='M')<<1+m&1],2)
m+1
EndIf
Next i
If v
p=SendMessage_(GadgetID(#Lst),#LVM_APPROXIMATEVIEWRECT,-1,-1)>>16
i=ScaleDown(p+3)
If i<w
w=i
ResizeGadget(#Lst,#PB_Ignore,#PB_Ignore,#PB_Ignore,w)
EndIf
EndIf
WindowBounds(0,\Width/2,w,\Width*2,w)
SetWindowCallback(@ResizeWindows(),#Win)
SetGadgetState(#Lst,a-Bool(a=m))
SetActiveGadget(#Lst)
StickyWindow(#Win,#True)
HideWindow(#Win,#Null)
c=-1
h=-1
Repeat
n=Bool(GetAsyncKeyState_(#VK_CONTROL)&32768)
If n<>c
c=n
PostEvent(#WM_MOUSEMOVE)
EndIf
Select WaitWindowEvent()
Case #PB_Event_Gadget
c=EventType()
Select c
Case #PB_EventType_LeftClick,#PB_EventType_LeftDoubleClick
Jump(GetGadgetState(#Lst),Bool(c=#PB_EventType_LeftDoubleClick))
EndSelect
Case #PB_Event_Menu
c=EventMenu()
Select c
Case #KeySync,#KeyGo
n=GetGadgetState(#Lst)
If n>=0
Jump(n,Bool(c=#KeyGo))
EndIf
Case #KeyExit
End
EndSelect
Case #WM_CHAR
n=(EventwParam() | $20)
Select n
Case 'a' To 'z'
n-'a'
Case '0' To '9'
n-22
Default
n=FindString(#CharactersAboveNumbers,Chr(n))
If n
n+25
Else
n=999
EndIf
EndSelect
If n>=0 And n<m And n<36
Jump(n,#True)
EndIf
Case #WM_MOUSEMOVE
n=-1
If c
i=GadgetID(#Lst)
GetWindowRect_(i,rect)
GetCursorPos_(dot)
If PtInRect_(rect,dot\y<<32 + dot\x)
ScreenToClient_(i,@dot)
Info\pt=dot
n=SendMessage_(i,#LVM_GETHOTITEM,0,0)
EndIf
EndIf
If n<>h
h=n
If h>=0
t=""
v=Val(GetGadgetItemText(#Lst,n,1))
i=v-#MarkerTooltipLines>>1
While i<=v+#MarkerTooltipLines>>1
If i>0 And i<=\Lines
s=Source(i)\Code
If Len(s)>#MarkerTooltipLineLength
s=Left(s,#MarkerTooltipLineLength)+"..."
EndIf
t+Str(i)+" "+Chr(Bool(i=v)*13+32)+" "+ReplaceString(s,#TAB$," ")+#LF$
EndIf
i+1
Wend
Select n
Case 0 To 25
s=" around Marker '"+Chr('A'+n)+"'"
Case 26 To 35
s=" around Marker '"+Chr(22+n)+"'"
Default
s=""
EndSelect
ToolTip("Code lines"+s,t)
Else
ToolTip("","")
EndIf
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Else
OpenWindow(#Win,ScaleDown(GetSystemMetrics_(#SM_CXFULLSCREEN))-210,4,200,0,"No Markers found...",#PB_Window_SystemMenu|#PB_Window_NoActivate)
n=0
While n<100
WaitWindowEvent(10)
n+1
Wend
EndIf
EndIf
EndWith
EndProcedure
Main()