You are here: PSPad forum > České diskuzní fórum > Námět - Navigátor...

Námět - Navigátor...

#1 Námět - Navigátor...

Posted by: Semi | Date: 2020-07-24 02:17 | IP: IP Logged

Mám další návrh na jednoduché vylepšení:

Navigátor se seznamem funkcí, nebo sekce v IniFile, nebo objekty v DFM atd...
Něco jako je v Delphi "Code Explorer", stačí to jednodušší...

Mám na stisk třeba F6, otevře se okno s ListBoxem (nebo to můžete mít jako další záložku vlevo v "Tool panel"), kde je seznam funkcí a objektů, na psaní z klávesnice vyhledává (komponenta TIncSearch), na OnClick nebo listování šipkou v seznamu nastavuje pozici v Editoru na tu funkci, na OnDblClick nebo klávesou Enter to vybere funkci a zavře seznam...

Ohromě to ulehčuje navigaci v delších unitách nebo v knihovnách javascriptových nebo PHP funkcí... Sice to jde i Ctrl+Home, Ctrl+E vyhledávat, ale když je tam stejný string víckrát, tak to je dlouhé dohledat to správné místo s obsahem funkce a ne její volání... (Např. hledám "TEvalBitmap.CallFunc": F6,"bitmap.call",Enter... Kdybych jenom hledal "bitmap.call" v textu, tak to je X-krát, když se ta funkce volá, a pak někde jednou, když je deklarovaná...)

Když se seznam otevírá, stojí na té řádce, která je nejblíž předchozí aktuální pozici v textu, a ta je vidět zhruba v polovině toho ListBoxu. {např. TopIndex:=Max(ItemIndex-(Height div (16*2)),0); při prvním zobrazení, a zachovat vrchní položku v ListBoxu při aktualizaci seznamu...}
Takže na první pohled vidím seznam pár předchozích a následujících funkcí a na pár šipek a Enter se přesunu na nějakou vedlejší funkci, nebo šipka nahoru a dolu na začátek aktuální funkce...

-----

Přemýšlel jsem, jestli by to šlo uživatelsky konfigurovatelné přes ten JScript, ale bylo by to složitější...

Napsal jsem vám na to unitu v Pascalu, je to buď ansi nebo unicode...
V Delphi 5 jsem to odladil a funguje to, v Rad Studio 10 to jde přeložit a zřejmě by to fungovalo také, nebo si to můžete opravit...

TextNavig.zip

Má to základní výpis navigačních bodů pro PAS, DFM, INI, Javascript/C/PHP, a String navigator...
Zřejmě by se to vybralo podle high-lighteru? Případně by šly napsat další, když mi pošlete ukázku...

Nevím, co by mělo být jako navigace v HTML, možná výpis elementů s name= nebo id= atributy?
Pro HTML nebo XML by byl lepší TreeView...


type
// User callback function:
// Result: True=found/stop, False=continue
// Name is text for navigation list
// CP is 0-based offset in Text
TEnumNavigPoints=function(Arg: Pointer; const Name: String; CP: Longint): Boolean;
//
// Various types of NavigPoint scanners:
TNavigPointScanner=function(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;


// [IniFile] ...
function EnumIniNavigPoints(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;
// Pascal
function EnumPasNavigPoints(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;
// Dfm
function EnumDfmNavigPoints(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;
// Js works for Javascript, PHP, EvalScript, C, ...
function EnumJsNavigPoints(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;
// general strings:
function EnumPasStringNavigPoints(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;
function EnumAnyStringNavigPoints(const Text: String; const Enum: TEnumNavigPoints; Arg: Pointer): Boolean;

Asi by se ten seznam neměl aktualizovat na každé OnChange v Editoru, kdyby byl otevřený nemodální, to by asi zdržovalo v psaní, to stačí v OnActivate toho listu, nebo jednou při jeho zobrazení... (pak je otázka, jak v tom seznamu udržovat CP pozice v textu, když se něco mění a seznam je otevřený...? Ono se dá jen projít ten seznam a aktualizovat integer pozici následujících položek o delta změnu, což by zdržovat nemuselo... Seznam může mít i přes 1000 položek u delších unit... U mě to pro unitu 2.5Mb s 1800 funkcemi běží cca 60msec, nevím nakolik zdržuje standardní TListBox a nakolik Editor, aby vytáhnul celý Text do jednoho stringu... Aktualizovat na OnChange by to zdržovalo, leda by to jelo v jiném threadu nebo s timerem na pár vteřin od poslední změny nebo KeyDown ...)
Stačilo by to i modální, je to jednodušší, že se to nemusí průběžně aktualizovat...

Options: Reply | Quote | Up ^


#2 Re: Námět - Navigátor...

Posted by: vbr | Date: 2020-07-24 09:32 | IP: IP Logged

Zdravim,
v PSPadu je Pruzkumnik kodu v menu Nastroje - zda se, ze vetsina funkci se podoba popisu - seznamy funkcnich definic, trid, promennych aj. s moznosti synchronizovani s textem kodu.

vbr

Options: Reply | Quote | Up ^


#3 Re: Námět - Navigátor...

Posted by: Semi | Date: 2020-07-24 14:54 | IP: IP Logged

Aha, už jsem to našel...

(Býval bych to sem asi nepsal, kdybych to našel předtím...)

Ten je dost na nic, viz srovnání, jak se to otevře:
image

Ten můj návrh se hodí na navigaci při psaní kódu té unity, že třeba hned vidím, kde v unitě jsem, a na první pohled a kliknutí se dostanu na sousední funkci před touto nebo za touto.

Nepotřebuji navigaci na jednotlivé funkce v deklaraci objektů, stačí mi jedna řádka za objekt. (Tam je vidím logicky uspořádané do skupin často na jedné obrazovce, abecedně je to nepřehledné...) Ale je potřeba navigace na kód všech těch funkcí dole v sekci implementation, ať už od objektů nebo další místní funkce v unitě...

Když v tom "Code Explorer" v PSPad dám refresh, tak se přesune na začátek na "procedures". A je to tříděné abecedně a ne v pořadí v kódu...

Je tam jenom interface unity...
Nezobrazuje to ClassName objektů, je tam "protected", "public" a v tom jména funkcí, která jsou skoro stejná ve všech objektech v téhle unitě... (Poznámka k obrázku - žádný objekt v té unitě nemá ani "published", ani "class base" funkce... To má ten explorer také chybně... Kliknutí na node "published" se nastaví na začátek textu na pozici 0... V node "published" nebo "class base" jsou leckde funkce ze sekce "protected" a někde i z příštího objektu...)

Nahoře ve stromku je "procedures", "functions", "public", a tam jsou abecedně seřazené smíchané globální funkce unity a funkce z většiny interface. A pak ty nepojmenované node objektů s "protected","public" a seznam funkcí...

Na některou kliknu, a jsem v hlavičce toho pas na deklaraci té funkce. Jenže PSPad neumí Ctrl+Shift+Down navigaci na pascal tělo funkce a zpět. Tahle zkratka hledá příští/předchozí výskyt... Všechny objekty v unitě mají override na stejnou funkci, to se za příští/předchozí výskyt hledá dlouho...

Někde rozkliknu node "class base" a kliknu na funkci, ok, něco vidím, není to ono... Zabalím ten Node "ClassBase" a Editor se postaví na začátek unity (pozice 0), ztratím to místo, kde byl ten objekt... Třeba kde má ve stromku "published" i když žádné published nemá, když na to kliknu, editor stojí na začátku unity...
--> Když tam není v Node žádná pozice, tak to nemá chodit na 0...

Tohle je na koukání do cizích unit, kdybych hledal, jakou syntaxi má ta funkce, ale nijak to nepomáhá v navigaci v textu implementation, když tu unitu píšu...

Objekt, který má dvakrát protected, to má ve stromku v pod-úrovni 2x...

Nejsou tam "record"...

U některých unit se Ctrl+Shift+E zobrazí dobře. U téhle dlouhé unity Ctrl+Shift+E zobrazí šedý Explorer a "Not implemented for this file type". Když se překliknu na Explorer a zpátky do Editoru, tak se to naplní...

-----

Zkusil jsem si jako u druhého programu najít tu funkci TEvalFloatMap.CallFunc... Ctrl+Home,Ctrl+E, TFloatMap.Call - nenašel to, spletl jsem se a v hledacím políčku nejde opravovat na začátku... Tak Esc,Ctrl+E, TEvalFloatMap.Call - zůstane tam jenom až po C, protože to v tom textu už není, protože tím prvním hledáním jsem se dostal za ten bod v kódu. Takže ještě jednou, Esc, Ctrl+Home, Ctrl+E, TEvalFloatMap.Call, a našel jsem to, na 56 key-stroke... Jednou jsem spletl classname, to se mi stává, je tam těch classů hodně...
U mě hledám F6,floatmap.call,enter a jsem tam... Ne na volání "FloatMap.CallFunc()" někde v kódu, ale na deklaraci té funkce... Když je u mě ve žlutém hledacím políčku překlep, zčervená ale napíše to, co jsem tam napsal, můžu se šipkami vlevo dostat na začátek k překlepu a opravit to...
Tady v PSPad si překlepu v Ctrl+E všimnu, až když to dopíšu, že to tam od místa s překlepem až do konce celé chybí, musím se Backspace vrátit a napsat to znovu...

-----
Na Javascript tam je explorer lepší, ale trvá mu to několik vteřin (na knihovně funkcí 150kb)...

Proměnné v javascriptu jsou zajímavé, ale když některou rozkliknu, nějak jsem to nepochopil... Některé tam mají svých pár výskytů v dané funkci... Některé tam mají výskyty v celém kódu včetně komentářů a i výskyt ve stringách...

-----
Hledat z klávesnice to TreeView sice trochu umí, ale nevidím hledaný text. Když je v hledání překlep, tak už nic nenajdu... Leda šipkami zrušit hledání a znovu hledat celý text. Ale to najde jenom první výskyt, kdežto to žluté políčko IncSearch mívá u mě hledání příští,předchozí šipkami...
(Teď zkouším, v editoru žluté políčko Ctrl+E neumí hledat příští,předchozí ani šipkami, ani F3, hned se zavře... Delphi to umí, je to dost logicky očekávatelná funkce... Žluté políčko by mělo na šipky vlevo vpravo normálně pohybovat v editu a nezavírat... Když umístím kurzor myší doprostřed a vložím písmeno, tak by neměl mazat zbytek textu... Třeba když tam chci dopsat tři písmena doprostřed hledaného názvu, zadám první a zbytek se smaže, protože takhle to nenašel, ale kdyby počkal, až to doplním, tak by to pak našel...)

-----
PHP navigátor je dobrý...

(Je vidět, že na PHP nebo Javascript se PSPad používá víc, než na pascal...)

-----
Ještě by mohl, když kliknu na funkci, tak aby kolečko myši fungovalo v editoru...
(To samé vlevo v průzkumníkovi souborů, aby kolečko fungovalo v seznamu souborů nebo složek bez toho, abych tam klikal...)

Umí to Delphi, umí to Firefox, umí to OpenOffice (možná jen když je nastavené X-mouse v systému?), uživatelé už mohou být zvyklí, že MouseWheel kolečkuje tam, kde ukazuje šipka, a ne, kde byl focus...

Protože když si zapnu v Code Explorer "Set focus to editor after goto", tak po kliknutí na funkci funguje kolečko v editoru, ale zase nefunguje kolečko myši v exploreru, a když do něj kliknu, tak zase focusuje editor a nedá se mu dát focus... (Dá, třeba klik kolečkem... Je to nepohodlné...)

Options: Reply | Quote | Up ^


#4 Re: Námět - Navigátor...

Posted by: vbr | Date: 2020-07-24 19:06 | IP: IP Logged

Zdravim,
urcite ma pruzkumnik kodu sva omezeni, je urcen pro pokud mozno jednotne zakladni zpracovani mnoha jazyku, takze s adresne vytvorenym IDE pro jednotlive jazyky se moc neda porovnavat.
Souhlasim, ze abecedni serazeni polozek vetsinou moc prehledne neni, nastavuje se v
Nastaveni: Nastaveni Nastroju: [ ] Seradit obsah pruzkumnika kodu podle abecedy. (cekal bych ze vypnute razeni je vychozi nastaveni, ale nejsem si jisty).

Pokud by ukazane nastroje bylo mozne propojit s PSPadem externe, napr. v ramci skriptoveho rozhrani jako nebo nastroje z panelu, bylo by to myslim pro nektera pouziti zajimave.

vbr

Options: Reply | Quote | Up ^


#5 Re: Námět - Navigátor...

Posted by: pspad | Date: 2020-07-24 19:13 | IP: IP Logged

Parsovaci funkce se postupně vyvíjejí, jak chodí připomínky.
Pokud he něco špatně nebo pomalé, stačí poslat vzorový zdrojak se stručným popisem

Options: Reply | Quote | Up ^


#6 Re: Námět - Navigátor...

Posted by: Semi | Date: 2020-07-25 03:38 | IP: IP Logged

Posílal jsem zdroják na parser pascalu a dalších, snažil jsem se to poslat jako dobrý podnět a něco pro to taky sám udělat...
TextNavig.zip
(Kdybych býval našel Code explorer, ušetřil bych si pár hodin s psaním tohoto...)

Ukázku pascalu, co to parsuje špatně, viz Eval.zip a tam třeba soubor Source\UEvalG32.pas nebo Source\UEvalSql.pas ...
Nebo třeba SqlIntf.pas, kde jsou jen samé interface, jeden objekt a dvě funkce... Code Explorer to všechno smíchá dohromady...

Když jsem o tom přemýšlel, vy asi ten "Object pascal" máte na Unit1.pas kde je objekt TForm1=class(TForm) a nemusíte ani psát, jaký class tam má public/private metody...?

Nemá smysl rozdělovat "procedures" a "functions", je to to samé a jen se to znepřehledňuje...

Ohledně třídění - našel jsem to v nastavení a je to vypnuté a stejně se to pro pascal třídí abecedně... (Javascript a PHP jsou správně v pořadí, jak jsou v kódu...)

-----

Další poznámka: když drag-drop z externího souborového manageru otevírám nový soubor, mohl by se otevřít vedle aktuální záložky a ne na konci workspace... Třeba Firefox to umí nastavit někde v konfiguraci, že nová záložka se otevírá vedle aktuální... Ony sice jdou přetahovat myší, ale to jen když jich je tam pár...

Logické zdůvodnění je, že dropovaný soubor má často vztah k tomu, co právě píšu, a budu se mezi nimi chtít rychle přepínat Ctrl+Tab a Ctrl+Shift+Tab...
A jako uživatel nad tím mám tu kontrolu, že než tam dropnu soubor, tak se nastavím na tu záložku, vedle které ho chci mít otevřený...

-----

Jestli by to šlo jako uživatelský modul? To nevím...
Z JScript si neotevřu GUI okno se seznamem...

Používá se komponenta odvozená z TSynEdit, na to by asi šlo udělat externí plugin...

Kdyby to umělo načítat DLL pluginy, bylo by to jednodušší, takhle by se asi musel zaregistrovat v systému a vytvářet z JScript init() funkcí new ActiveXObject("...") ...?
Řekl bych, že se s tím teď dělat nebudu...

Jen jako proof-of-concept, vytažení textu z aktuálního editoru a text pro navigátor:

eval.exe -dll EvalTaskUtil -dll EvalTest "var Wnd:=FindWindow('TfPSPad'); if(!Wnd)#r E('PSPad not found'); var Mdi:=FindWindow(Wnd,0,'MDIClient',null), P0:=GetWindow(Mdi,GW_CHILD), wEdit:=FindWindow(P0,0,'TPSSynEdit',null); if(!wEdit) #r E('Top Editor not found'); var hInst:=GetWindowLong(wEdit,GWL_HINSTANCE), tp:=GetWindowThreadProcessId(wEdit), tid:=tp.Thread, A:=GlobalFindAtom(Fmt('ControlOfs%.8x%.8x',hInst,tid)), Ctrl:=GetWinProp(wEdit,A); if(!Ctrl) #r E('SynEdit not found'); var Proc:=OpenProcess(tp.Process), Mem:=Proc.Memory, Lines:=Mem.ReadInt(Ctrl+0x2d8), Count:=Mem.ReadInt(Lines+0x24), List:=Mem.ReadInt(Lines+0x20), Stm:=RSt(); Stm.CodePage:=utf8; for(i=0;i<Count;i++){ var pwc:=Mem.ReadInt(List), len:=pwc?Mem.ReadInt(pwc-4):0, Text:=(len>0)? Mem.ReadText(pwc,1200,len):''; List+=0x18; Stm.WriteLine(Text); } Stm.Seek(0); EnumPasNavigPoints(Stm.toString(),#f(Name,Cp){ L('%d: %s',Cp,Name); });" | tvw

(Trvá to 860 msec takhle ze scriptu pro unitu 2.5Mb, 85k řádek, v DLL načtené v PSPadu by to bylo rychlejší a ty offsety by tam nebyly napevno, ale dohledal bych si ten TSynEditStringList pečlivěji...)

Options: Reply | Quote | Up ^


#7 Připomínka - Klávesové zkratky...

Posted by: Semi | Date: 2020-07-25 05:35 | IP: IP Logged

Zkouším si předefinovat klávesové zkratky, přehodit Ctrl+J a Ctrl+Space...

Ale shortcut Ctrl+Space nejde zadat, je tam Ctrl +, a když zmáčknu mezeru, tak tam je "není"...
V poli "New Shortcut", když je zmáčknutý Shift, je tam "Alt +" ...
(Že by to na XP nefungovalo?? Možná...)
(Jde to ale opravit v KeyMap.ini)

-----
Ještě k tomu žlutému hledacímu políčku... Kdysi jsem o tom psal článek o TIncSearch...

Ale až nedávno mě napadla jedna dobrá vychytávka:

Když hledám v seznamu (listbox atd) a kurzor je na konci textu toho hledacího políčka, tak šipkou vpravo, pokud je v listboxu aktuálně zadaný text nalezený, tak doplním jedno další písmeno...

Takže ten hledaný text nemusím zadávat...

Např. v seznamu je aktuální GetWindowText a chci hledat GetWindowLong... Zmáčknu g, podržím šipku vpravo, dokud tam není getWindow, a dopíšu k tomu long... Nebo začnu někde na začátku, napíšu getw, vidím GetWindowText, tak šipkou doprava doplním až na getWindow a pokračuji v zadání hledaného textu...
Docela se tím urychluje zadání toho hledaného textu, když jsem třeba při hledání našel skoro podobný záznam, a jen se to někde na konci textu liší...
Typicky v seznamu, kde jsou položky TClassName.FuncName, tak zadám kousek začátku názvu třídy, šipkou vpravo doplním zbytek názvu až po tečku, a píšu FuncName... Někdy ty třídy mají dost dlouhý název...
Hledám TCustomSynEdit.InternalSetCaretXY , napíšu "cu", šipkou doprava doplním až na konec názvu třídy, mám "customSynEdit", napíšu ".int", šipkou doprava doplním až k "X", a napíšu "y" a jsem tam... (ta šipka to v autorepeat zadá rychleji, než bych to napsal...)

Options: Reply | Quote | Up ^


#8 Re: Připomínka - Klávesové zkratky...

Posted by: pspad | Date: 2020-07-25 18:42 | IP: IP Logged

Co se týká klávesových zkratek, Delphi komponenta neumí vložit všechny zkratky. Pak je třeba po vybrání Mapa kláves použít tlačítko přímá editace. Tam už jde pak napsat cokoliv.

Co se týká inkrementálního hledání, není to špatný nápad. Přidám si to do seznamu.

Options: Reply | Quote | Up ^


#9 Re: Námět - Navigátor...

Posted by: pspad | Date: 2020-07-27 11:15 | IP: IP Logged

K parseru kodu pro Pascal

Byla tam chyba, takže vypadly třídy ze struktury.
Odstranil jsem automatické řazení, teď se bude řídit parametrem
Sloučil jsem funkce a procedury, budou se lišit barvou ikonky

Obecně - myš

Kolečko myši funguje nad tím, nad čím je aktuálně myš bez ohledu na to, kde je focus. Pokud mám myš nad textem editoru, skroluje kolečkem text v editoru, pokud kurzor přesunu nad průzkumník, skroluje text v průzkumníkovi.

Mohl bych poprosit o nějaký JScript se spoustou funkcí, u kterého trvá parsování dlouho?
Buď vypnu proměnné a jejich výskyty úplně nebo to podmíním velikostí zdrojáku.

Options: Reply | Quote | Up ^


#10 Re: Připomínka - Klávesové zkratky...

Posted by: pspad | Date: 2020-07-28 17:27 | IP: IP Logged

Incrementální hledání

Další buld bude umět:
TAB - přidá zbytek do konce slova
Šipka vpravo - přidá další znak

Options: Reply | Quote | Up ^






Editor PSPad - freeware editor, © 2001 - 2020 Jan Fiala, Hosted by Webhosting TOJEONO.CZ, design by WebDesign PAY & SOFT, code Petr Dvořák, Privacy policy and GDPR