Recent

Author Topic: Autocomplete question while coding  (Read 4037 times)

darkcyber

  • Newbie
  • Posts: 4
Autocomplete question while coding
« on: June 04, 2020, 05:42:56 am »
I know as you type code in Lazarus should give an auto popup with suggestions, like typing lblDisplay.Capt should popup and show .Caption and allow you to select that to autocomplete. For some reason, mine isn't doing this. I'm having to manually type in all the code, which isn't a big deal, but would like to have that shortcut if I could. I am using the version I downloaded directly from larazus-ide.org, the 32 bit, 2.0.8 version, if that helps.

Thanks!

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #1 on: June 04, 2020, 05:52:39 am »
I've just started Lazarus/FPC and getting the same issue, it's very annoying not having autocomplete. This is a very basic IDE requirement, how can we get it working?

Secondly, another issue is hovering over variables fails to display their value, as much IDE's do. Some do and other don't, they just show the type structure - which is no use to me. Is this a limitation again with Lazarus or FPC? If so, it needs to be sorted out pronto, we can't debug efficiently without this feature and it's back to .NET otherwise. Ah..

dsiders

  • Hero Member
  • *****
  • Posts: 1052
Re: Autocomplete question while coding
« Reply #2 on: June 04, 2020, 07:14:39 am »
I know as you type code in Lazarus should give an auto popup with suggestions, like typing lblDisplay.Capt should popup and show .Caption and allow you to select that to autocomplete. For some reason, mine isn't doing this. I'm having to manually type in all the code, which isn't a big deal, but would like to have that shortcut if I could. I am using the version I downloaded directly from larazus-ide.org, the 32 bit, 2.0.8 version, if that helps.

Thanks!

https://wiki.freepascal.org/IDE_Window:_Editor_Options_Completion_Hints
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

dsiders

  • Hero Member
  • *****
  • Posts: 1052
Re: Autocomplete question while coding
« Reply #3 on: June 04, 2020, 07:14:54 am »
I've just started Lazarus/FPC and getting the same issue, it's very annoying not having autocomplete. This is a very basic IDE requirement, how can we get it working?

Secondly, another issue is hovering over variables fails to display their value, as much IDE's do. Some do and other don't, they just show the type structure - which is no use to me. Is this a limitation again with Lazarus or FPC? If so, it needs to be sorted out pronto, we can't debug efficiently without this feature and it's back to .NET otherwise. Ah..

https://wiki.freepascal.org/IDE_Window:_Watch_list#Watch_Properties
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Autocomplete question while coding
« Reply #4 on: June 04, 2020, 09:06:49 am »
Secondly, another issue is hovering over variables fails to display their value, as much IDE's do. Some do and other don't, they just show the type structure - which is no use to me. Is this a limitation again with Lazarus or FPC? If so, it needs to be sorted out pronto, we can't debug efficiently without this feature and it's back to .NET otherwise. Ah..

If I have to take a guess than those that don't show are properties, especially if the property has a getter that is a method. The debugger won't execute such code, cause that could potentially result in a change of state of the debugged application.

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #5 on: June 04, 2020, 09:10:34 am »
https://wiki.freepascal.org/IDE_Window:_Watch_list#Watch_Properties

Thanks, but unfortunately, the Watch window and Locals Window still won't display any value other than basic scalar values, eg intereger, string. With all other types you just get the metadata and no actual values. Is this a limitation, if so, then it's impossible to work with this IDE and debug anything substantial. TStringList values can't be seen, neiether than property values. The Watch window doesn't even recognize Object.Property and says the property doesn't exists, eg TStringList.Count...I just can't get any values showing other than simple scalar. Am I dumb or is this a critical limitation of Lazarus? I can't believe the Delphi guys were working with such a limitation all these years, or were they? Thanks.

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #6 on: June 04, 2020, 09:15:17 am »
Is a TStringList.Count a settable property and therefore can't be viewed? If so, this is really huge flaw in the language and/or debugger. Here I was thinking debugging FreePascal was going to be relatively easily. Can't the IDE view "current values" of all properties or even traverse all structures and their values while in run mode? If not, an alternative would be to require all objects and types to implement a "ToString" method, at least the IDE could use that to display the current value. The implementation of ToString would be the responsiblity of the component itself. Just my 2c worth.

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #7 on: June 04, 2020, 09:17:51 am »
As I said, I can't even see the value of TStringList.Count in the Locals or Watch windows....gives a "property doesn't exist", yet the code runs fine.

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #8 on: June 04, 2020, 09:22:05 am »
Sorry to be of bother, but this is what I get when in Locals Window, then "Evaluate/Modify" a variable which is a populated TStringList....as you can see, no actual string values to be seen anywhere....what am I doing wrong? Thanks.

<TSTRINGLIST> = {
  <TSTRINGS> = {
    <TPERSISTENT> = {
      <TOBJECT> = {
        _vptr$TOBJECT = $aee1e0},
      FOBSERVERS = $0},
    FSPECIALCHARSINITED = false,
    FQUOTECHAR = 0 #0,
    FDELIMITER = 0 #0,
    FNAMEVALUESEPARATOR = 0 #0,
    FUPDATECOUNT = 0,
    FADAPTER = $0,
    FLBS = TLBSLF,
    FSKIPLASTLINEBREAK = false,
    FSTRICTDELIMITER = false,
    FLINEBREAK = $0,
    UPDATECOUNT = 0,
    STRICTDELIMITER = false,
    STRINGSADAPTER = $0},
  FLIST = $7ffff7f76c60,
  FCOUNT = 1,
  FCAPACITY = 4,
  FONCHANGE = {
    Proc = {
      procedure (POINTER,
      TOBJECT)} 0x7ffff7f6ffc0,
    Self = $0},
  FONCHANGING = {
    Proc = {
      procedure (POINTER,
      TOBJECT)} 0x7ffff7f6ffc0,
    Self = $0},
  FDUPLICATES = DUPIGNORE,
  FCASESENSITIVE = false,
  FFORCESORT = false,
  FOWNSOBJECTS = false,
  FSORTSTYLE = SSLNONE,
  DUPLICATES = DUPIGNORE,
  CASESENSITIVE = false,
  ONCHANGE = {
    Proc = {
      procedure (POINTER,
      TOBJECT)} 0x7ffff7f6ffc0,
    Self = $0},
  ONCHANGING = {
    Proc = {
      procedure (POINTER,
      TOBJECT)} 0x7ffff7f6ffc0,
    Self = $0},
  OWNSOBJECTS = false,
  SORTSTYLE = SSLNONE}

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Autocomplete question while coding
« Reply #9 on: June 04, 2020, 09:34:00 am »
Is a TStringList.Count a settable property and therefore can't be viewed? If so, this is really huge flaw in the language and/or debugger. Here I was thinking debugging FreePascal was going to be relatively easily. Can't the IDE view "current values" of all properties or even traverse all structures and their values while in run mode?

The TStringList.Count property uses a method as a getter. As I wrote above the debugger does not execute such methods by itself, because this has the potential to be dangerous and affect the state of the debugee. There is currently no way for the debugger to determine whether the method is "safe", "pure", "const", whatever. Take the following example which might illustrate the dangers better:

Code: Pascal  [Select][+][-]
  1. program ttest;
  2.  
  3. {$mode objfpc}
  4.  
  5. uses
  6.   SysUtils, SyncObjs;
  7.  
  8. type
  9.   TTestClass = class
  10.   private
  11.     fLock: TCriticalSection;
  12.     function GetWhatever: LongInt;
  13.   public
  14.     constructor Create;
  15.     destructor Destroy; override;
  16.     property Whatever: LongInt read GetWhatever;
  17.   end;
  18.  
  19. { TTestClass }
  20.  
  21. function TTestClass.GetWhatever: LongInt;
  22. begin
  23.   fLock.Acquire;
  24.   Result := 42;
  25.   Sleep(100);
  26.   fLock.Leave;
  27. end;
  28.  
  29. constructor TTestClass.Create;
  30. begin
  31.   fLock := TCriticalSection.Create;
  32. end;
  33.  
  34. destructor TTestClass.Destroy;
  35. begin
  36.   fLock.Free;
  37.   inherited Destroy;
  38. end;
  39.  
  40. var
  41.   t: TTestClass;
  42.   terminated: Boolean = False;
  43.   thd: TThreadID;
  44.  
  45. function ThreadFunc(parameter: pointer): ptrint;
  46. begin
  47.   while not terminated do begin
  48.     Writeln(t.Whatever);
  49.     Sleep(10);
  50.   end;
  51.   Result := 0;
  52. end;
  53.  
  54. begin
  55.   t := TTestClass.Create;
  56.   try
  57.     thd := BeginThread(@ThreadFunc);
  58.     Sleep(1000);
  59.     Terminated := True;
  60.     WaitForThreadTerminate(thd, -1);
  61.   finally
  62.     t.Free;
  63.   end;
  64. end.

Now if you stop the execution of this in the debugger there is a chance that your code might be inside TTest.GetWhatever while the lock is held. If the debugger would now try to evaluate TTest.Whatever the debugger would lock up, because the code would never return.

If not, an alternative would be to require all objects and types to implement a "ToString" method, at least the IDE could use that to display the current value. The implementation of ToString would be the responsiblity of the component itself. Just my 2c worth.

Good laugh! Free Pascal is built on backwards compatibility. Requiring every class to implement a specific function would render nearly all code uncompilable out there not to mention that it would have the same problems as executing property getters has!

See also here and here.

Sorry to be of bother, but this is what I get when in Locals Window, then "Evaluate/Modify" a variable which is a populated TStringList....as you can see, no actual string values to be seen anywhere....what am I doing wrong? Thanks.

The strings are stored inside the FList field.

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #10 on: June 04, 2020, 09:58:19 am »
Glad you had a good laugh on me.

Seriously, what's the difference between Lazarus and the rest of the IDE's out there that manage to show you variable values while debugging?

For instance, I can't even see the value of "textbox.text" while debugging, so what's the point of using this IDE or even Pascal in that case?
With my limited knowledge of compilers and interpreters (having written some in the past), I can only guess that Lazarus doesn't have underlying access to the compiler variables while FPC is running, with no underlying interface exposed, hence it needs to call a "getter" in order to retrieve something as simple as "textbox.text". Is this correct? So, could the FPC be modified to include hooks for the IDE?

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #11 on: June 04, 2020, 10:02:06 am »
Assuming then, it's not possible to check variable values while debugging, what is the best way to debug these programs? What do you recommend? Thanks.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Autocomplete question while coding
« Reply #12 on: June 04, 2020, 10:33:00 am »
Seriously, what's the difference between Lazarus and the rest of the IDE's out there that manage to show you variable values while debugging?

Any IDE has to deal with these problems. In some cases these can be easier solved (e.g. on CLR or JVM based languages the runtime can and does help here), in others (for example C++) this isn't as easy. For example I just tested a C# program with a class that has a property getter that simply does a Sleep(5000) before returning. Visual Studio then said hat a timeout was reached and the evaluation was aborted. And any property that followed (lexically) after that was aborted as well. This is something a CLR targetting debugger can handle due to it working together with the runtime. With pure machine code this is different however as the code can pull anything and you can't simply store the state and restore it. And while most getter code will probably behave nicely the debugger must deal gracefully with the nasty cases otherwise you'll have the next complains.

For instance, I can't even see the value of "textbox.text" while debugging, so what's the point of using this IDE or even Pascal in that case?
With my limited knowledge of compilers and interpreters (having written some in the past), I can only guess that Lazarus doesn't have underlying access to the compiler variables while FPC is running, with no underlying interface exposed, hence it needs to call a "getter" in order to retrieve something as simple as "textbox.text". Is this correct? So, could the FPC be modified to include hooks for the IDE?

Again, it's not the IDE, it's the debugger. And writing debuggers is hard. If the debugger would provide the information to the IDE than everything would work already, but the debugger does not. For example Microsoft has probably sunk millions of Dollars into their debugging engines (Visual Studio, WinDbg, etc.), but Lazarus relies on GDB which like most Open Source software is mainly developed by volunteers.

Assuming then, it's not possible to check variable values while debugging, what is the best way to debug these programs? What do you recommend? Thanks.

You can check variables and fields as well as properties that directly use fields without problems, it's only properties that call a getter method that are the problem. In most cases you can help yourself by directly accessing the field. E.g. to get the entry count of a stringlist you could (while debugging) write into your source YourStrList.FCount (you don't even need to save the file!), hover your mouse over the FCount and get the value. Then you remove that again and continue debugging. If you need it more often you can add that expression to the watchlist. You'll need to know how the property is implemented however.

jamie100

  • New member
  • *
  • Posts: 8
Re: Autocomplete question while coding
« Reply #13 on: June 04, 2020, 01:47:06 pm »
Thanks,
Using TStringlist.FCount seems to work with hover and debug, whereas .Count couldn't be retrieved in any debug window (property does not exist>). So what's the difference between those F variables and the regular properties and should we use them in code? Thanks

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Autocomplete question while coding
« Reply #14 on: June 04, 2020, 02:16:12 pm »
TStringList is essentially declared like this (simplified):

Code: Pascal  [Select][+][-]
  1. type
  2.   TStringList = class
  3.   private
  4.     FCount: LongInt;
  5.   protected
  6.     function GetCount: LongInt; virtual;
  7.   public
  8.     property Count: LongInt read GetCount;
  9.   end;
  10.  
  11. function TStringList.GetCount: LongInt;
  12. begin
  13.   Result := FCount;
  14. end;

Using the debugger you can't use the property TStringList.Count, because that involves calling a function which is currently a no-go. As the debugger doesn't care about visibility however you can easily ask it to evaluate the field TStringList.FCount instead. In this specific case this will lead to the desired result (there can be cases in which this won't work).

What won't work however is you using the field FCount inside your own code, because that field is declared as private, thus you can't access it.

Sidenote: in Object Pascal it's common to prefix fields with F (just like in C++ one that is often seen is m_) while methods and properties don't have prefixes. You don't need to follow this, but you'll see this in many other code.

 

TinyPortal © 2005-2018