Jump to content
Stefan Glienke

Introducing Delphi Uses Helper

Recommended Posts

I tried, but cannot get it to show. Shift+Ctr+A just locks the IDE for about 20 seconds and then the default uses thingy (I forgot how bad it is) shows. I tried changing the shortcut but then nothing happens. Testing with 10.4.2 

 

Share this post


Link to post

And I have to say, Why TF isn't something like this built into the IDE?? 

 

Nice work. It almost feels like I'm using visual studio 2012 :classic_biggrin: I ended up using Shift+Ctrl+U as the shortcut so I never have to see the crappy default one - which I accidently invoked a few times now. 

 

Now for the first feature request 😉. Can you index my project search path? I just tried to us it to add Spring.Collections - but that is installed via dpm - so it's on my search path (via an msbuild property). 

 

This tool as a ton of potential... I know you don't have the time to work on it but others might, if you put it on github 😉

Share this post


Link to post
Posted (edited)
7 hours ago, Stefan Glienke said:

Introducing "Uses Helper" - some little but incredibly helpful IDE plugin

Since I seem to remember that you mentioned that you use GExperts:

The description of your plugin sounds a lot like the Identifiers tab of the Uses Clause Manager.

What functionality are you missing there that you went to the trouble to write your own?

Edited by dummzeuch
  • Like 1

Share this post


Link to post
Posted (edited)
9 minutes ago, dummzeuch said:

What functionality are you missing there that you went to the trouble to write your own?

Maybe the fact that I just can hit a shortcut and press enter in less than a second to add a uses without completely being disturbed by that UI?

It's just a different mindset - I loved the way Visual Studio handled this with their quick action system and wanted it like that in Delphi as well.

 

Maybe I am missing something but tell me the steps to add the containing unit once I declare a variable of type TWuppdi with GExperts. With UsesHelper while on TWuppdi I press Ctr+Shift+A Enter and the unit is in the uses.

Edited by Stefan Glienke

Share this post


Link to post
25 minutes ago, Stefan Glienke said:

Maybe I am missing something but tell me the steps to add the containing unit once I declare a variable of type TWuppdi with GExperts. With UsesHelper while on TWuppdi I press Ctr+Shift+A Enter and the unit is in the uses.

  • you press the shortcut that calls the expert
  • if the Identifier tab is not yet active (the dialog remembers which tab was active), press the shortcut (Alt+I) for that
  • if there is a perfect match, the required unit will automatically be selected, so you press Alt+C or Alt+L to insert the unit into either the interface or implementation section
  • if the expert is configured for - oops? - I thought there was an option to automatically close the dialog after adding a unit? OK, apparently somehow this option got lost, I need to look into that - you press enter to close the dialog

So, if there is a perfect match, 3 key presses / combinations are required.

If there isn't, you can either use the filter or the keyboard keys to select the correct identifier / unit to insert.

 

The expert uses the current search path to determine which units are available. One drawback of this is that it might take a few seconds to determine the units and parse / cache the identifiers when invoked the first time for a project and display them. There definitely is still room for improvement here. But on a computer with an SSD it's very fast, on a HDD it's not too bad either.

Share this post


Link to post
Posted (edited)
13 minutes ago, dummzeuch said:

The expert uses the current search path to determine which units are available.

Yeah, not gonna work - my search paths don't include much pas files.

 

13 minutes ago, dummzeuch said:

on a computer with an SSD it's very fast

Takes 3 seconds to list System.Classes when I type TStringList (every time!) - and thats with an SSD - too slow.

 

Uses Clause Manager has its use (personally I am never using it) but for that specific task its just too cumbersome for my taste.

 

UsesHelper is an addition to the toolbox and focuses on one thing to do that as simple and efficient as possible and also has its potential drawbacks of possibly running out of sync as the index is not being built every time. But as I see it the code being indexed is mostly library code that does not change anyway - all units explicitly part of a project are indexed every time.

Edited by Stefan Glienke

Share this post


Link to post
Posted (edited)

I'm using this since you (pre-)released it back in the G+ era and I'm very grateful to you for creating it.

Edited by Attila Kovacs
  • Thanks 1

Share this post


Link to post

@Stefan Glienke

Well Stefan, it seems we had similar thoughts, as I presented my "poor man's" solution some days ago.

Congratulations, of course you had that full fledged IDE tool ready, probably doing a bit more and different than that.

I have to look deeper into it, but however the charm of my approach is that I don't need to install any helper at all.

 

Share this post


Link to post
2 hours ago, Stefan Glienke said:

Yeah, not gonna work - my search paths don't include much pas files.

That's why it also scans the browsing path. Sorry, I should have mentioned that. Otherwise it wouldn't have found TStringList in Classes:

2 hours ago, Stefan Glienke said:

Takes 3 seconds to list System.Classes when I type TStringList (every time!) - and thats with an SSD - too slow.

 

2 hours ago, Stefan Glienke said:

for that specific task its just too cumbersome for my taste.

So, the problem is, that it is too slow?

Or what else do do you mean by cumbersome?

 

I am trying to learn what to improve. For me it currently is fine (less than a second delay on the two computers I mostly work on, I wonder what makes it so slow on your computer), so I rely on others for suggestions.

Share this post


Link to post

Browsing path != the directories I want to index - also browsing path unfortunately does not work recursively and I will not add a million directories to browsing path just to be able to index our company source code which requires one line in the UsesHelper options.

 

I kindly suggest you install the plugin yourself and try it out, experiencing it yourself probably works best - I am not trying to sell you a product or compete with GExperts, I am just sharing something I found valuable and know that people using it (who also use GExperts btw) love it. If you aim for improving the GExperts experience please feel free to do so. Also they complement each other - like UsesHelper currently complains if the unit is already in a uses but you want to move it up or down - well then GExperts comes to the rescue. But for quickly coding away with as little intrusion as possible UsesHelper is just way better imho.

 

 

Share this post


Link to post

I just installed and tried it. It is indeed much faster than GExperts.

 

One observation: When no match is found, the error message is shown in the middle of the monitor. I would have expected it near the current cursor position like the other dialog.

  • Like 1

Share this post


Link to post
On 3/25/2021 at 2:50 PM, dummzeuch said:

less than a second delay on the two computers I mostly work on, I wonder what makes it so slow on your computer

Have a look at my commits #3476 and #3477. There was some rather odd code in TUnitIdentifierList.LoadFromFile which always wrote the cache file even if nothing had changed at all. It now never writes the file but instead returns False if it was in the old format. The caller will then parse the source code and write the cache file.

 

I haven't timed it but I think this should speed up the process significantly due to a lot less file system activity.

  • Thanks 1

Share this post


Link to post

Since I just stumbled  over the following declaration in Toolsapi.pas:

type
  TGetSrcLinesFunc = function (LineNum: Integer; ClientArg: Pointer): Integer {$IFDEF LINUX} cdecl; {$ENDIF} {$IFDEF MSWINDOWS} pascal; {$ENDIF}

  IOTAProcess90 = interface(IOTAProcess70)
    ['{BEBD67CA-F6FC-44A7-ACBF-E314DB085827}']
    { Indicates if process properties can be set on this process (via the thread view) }
    function CanSetProperties: Boolean;
    { Called when the user asks to set properties for this process (via the thread view) }
    procedure SetProperties;

Which breaks the GExperts unit exports parser because the code is invalid, if neither LINUX nor MSWINDOWS is declared, but I just tested your tool and it works:

I wonder how your tool handles this. Do you add one of these symbols to the parser?

If yes: It only has one index independently of the platform, so how does it decide which one to use while creating that index?

Share this post


Link to post

I explained that in the article. DelphiAST is being used to index using the defines of a Win32 application. 

Share this post


Link to post
11 hours ago, Stefan Glienke said:

I explained that in the article. DelphiAST is being used to index using the defines of a Win32 application. 

Opps, I missed the part about the standard defines. Sorry.

Share this post


Link to post
Posted (edited)
On 4/3/2021 at 12:08 PM, osterhaegar said:

Have a look at my commits #3476 and #3477.

@osterhaegar

I got the time until the list is shown and filtered down further. Consistently to about a second with my largest project (>5000 units, 140000 identifiers) on Delphi 2007. Reading the cache files for the units takes the longest time now. They are on an SSD, so there isn't much I can do unless I add them all to one project specific cache file, which I'm considering. With Unicode Delphis it's significantly worse though, there the sorting part takes more than half a second rather than 100 milliseconds. Again having a pre-sorted project specific cache file would help.

 

One unexpected cause for the delay was that I had set the timer, that checks whether the unit parser thread has finished, to 500 milliseconds. Reducing this to 50 milliseconds shaved off another 400 milliseconds from the total time.

 

(Yes, I timed it. I know that I claimed it took 1 second on my machine even before Osterhaegar's an my optimizations. That was wrong, it was more like 2.5 seconds for the above mentioned largest project. Smaller projects (like GExperts itself) took about 1.5 seconds.)

 

But at least I know now where the 3 seconds that Stefan experienced came from.

Edited by dummzeuch
  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×