Lazarus

Programming => General => Topic started by: Shpend on November 18, 2019, 04:48:44 pm

Title: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 04:48:44 pm
Hi folks,

I desperately want lazarus to be able to color in a predefined way, everything like this:

Code: Pascal  [Select]
  1.   type
  2.     TMyCustomColorForThisType1 = 0..100; //just some random code
  3.     TMyCustomColorForThisType2 = 0..100; //just some random code
  4.     TMyCustomColorForThisType3 = 0..100; //just some random code
  5.     TMyCustomColorForThisType4 = 0..100; //just some random code
  6.     TMyCustomColorForThisType5 = 0..100; //just some random code
  7.  

So in my fantasy, lazarus should color the "TMyCustomColorForThisType1..5" into a color i set up in the opensource lazarus editor.pas file.

But I would like to hear from you guys, which part of the lazarus package is the part where I can make this change happen via code.

I mean, feel free to also maybe implement this, since its a very nice feature to have, which all modern IDE's have, since mostly its more visually nicer code, atleast for me and a bunch of ppl :-D

Anyway, I would be super glad to hear from you guys about this!

Best regards

Shpend
Title: Re: Sourcecodeeditor typecolor customization
Post by: winni on November 18, 2019, 05:14:03 pm
Hi!

Have a look at this page to see how the color settings for the editor are done:

https://wiki.lazarus.freepascal.org/UserSuppliedSchemeSettings (https://wiki.lazarus.freepascal.org/UserSuppliedSchemeSettings)

If you click on one of the links in the first row of the table then you can see the related XML-File.

Winni
Title: Re: Sourcecodeeditor typecolor customization
Post by: JanRoza on November 18, 2019, 05:16:58 pm
Have you looked at the Lazarus Tools/options menu (Display-Colors)?
Almost anything in the Editor can be colorized to your personal taste there.
Ah, I see Winni was quicker than me.  :D
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 05:22:12 pm
hi thx for the fast response, but sadly my point got missunderstood, np!

I would like to have a dynamic color cusomization, since i am not willing of adding like 100 datatypes for each winapi and my own one, (medium size project)

So I would basically like telling lazarus editor, that, whenever he sees :

"type
   TypeA = Byte;
   TypeB = Char;
"
he shall color TypeA and TypeB into a predefined color, so spoken in algorithms, whenever he detects the "type" keyword and next a "=" sign, color all strings between these 2 parts.

Where can I do this, i sadly have no clue where in the open source code of lazarus i can make this happen :/
Title: Re: Sourcecodeeditor typecolor customization
Post by: JanRoza on November 18, 2019, 05:29:58 pm
I don't think it is wise to change the source of Lazarus, each new release of Lazarus will overwrite your changes.
No idea if many people have a need for what you want, I for one don't and have enough with the options Lazarus has now.
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 05:30:32 pm
Or actually, can u tell me where can I find the sourcecode of this
 "Tools-->--Settings-->Editor-->Displays-->Colors"

then I can look to create a new elementattribute which is called "types" and is distinguished from  (variable,  procedure, function) and you can then color these by your own :-)
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 05:31:59 pm
@JanRoza
this feature u dont need, is built-in  in any ususal IDE u know of any language, so there is a big need for it ;-)

and i want it for myself too, if u dont want it, ok, but i didnt ask who likes it and who not, i asked where can I find a solution to this
Title: Re: Sourcecodeeditor typecolor customization
Post by: JanRoza on November 18, 2019, 05:41:23 pm
Sorry for giving my personal opinion!  >:(
Title: Re: Sourcecodeeditor typecolor customization
Post by: winni on November 18, 2019, 05:43:33 pm
Hi!

Look at the directory lazarus/components/synedit .
There are around 25 file that start with synhighlighter

But you cannot decide the type of a variable just by one line of text:

126 can be a shortint, a smallint, a longint or an int64. OR: a byte, a word, a DWord or a Qword.
Similar with the char.

So you need a minimal parser to do your job.
That's using a sledgehammer to crack a nut.

Think about your plans.

Winni
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 06:02:03 pm
Hi winni!,

thx for this response, but what u mentioned is not an issue, since i want to collor (ALL) basic types as custom types, which are defined ofc as "type  TBlah = <Any Type here>" and i wanna color <Any type here> so it doesnt matter what 126 is, i just color all of them, and the base types I have already colored within the editorsettinfs in lazarus, so only the custom ones are missing, which i will color via code, so any new custom type will get colored in a specific color :)

THX in advance
Title: Re: Sourcecodeeditor typecolor customization
Post by: Martin_fr on November 18, 2019, 06:40:42 pm
I am still not sure what exactly you want....

Quote
Code: Pascal  [Select]
  1.  TMyCustomColorForThisType1 = 0..100;

1) You want the literal typename "TMyCustomColorForThisType1" to be colored?
So in
Code: Pascal  [Select]
  1. var Foo: TMyCustomColorForThisType1;
Code: Pascal  [Select]
  1. a := TMyCustomColorForThisType1(b);
The word TMyCustomColorForThisType1 will be colored?

1b)
You want type-names (e.g. TMyCustomColorForThisType1) colored ONLY within the "type" block in which they are defined?
(And maybe when they are used as type in "var" blocks)
But not in code (begin..end) blocks

2) You want any number from 0..100 to be colored? (never mind what type the number really is, but just because it potentially might be of a custom type)?



As for 1, you may want to look at https://wiki.lazarus.freepascal.org/IDE_Window:_Editor_User_Defined_Words
This will not automatically detect the type names though. You need to add each of them by hand.

1b could be done in a highlighter (though currently not implemented).

As for 2 - no luck.

Generally the HL is based on the current file, without knowing any other file  (the exception is IFDEF lowlight, which is driven by codetools).
So if file A contains "type TMyCustomColorForThisType1 = 0..100;" and file B contains "5" then the editor does not know about file A.
But even within the same file, that would need a complete rewrite of the way highlighting works.

Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 07:26:07 pm
Based on n your response: I want 1) and 1b)

So this "TMyCustomColorForThisType1 " shall be now colored ANYWHERE its used!

for 2) no, this i dont want.

"1b could be done in a highlighter (though currently not implemented)."

I hope so, but I dont know yet which highlighter would this be, since there are tons of files sadly which start with the work "synchighlighter"
Title: Re: Sourcecodeeditor typecolor customization
Post by: Martin_fr on November 18, 2019, 07:50:48 pm
It is SynHighlighterPas.pp

The highlighter does not make a list of known types. (So it does not have a list of all the names)

In type/var blocks (an it alreadyknows if it is in such a block), it could determine the type-names lexically.
- In a type block, anything before "=" is a type.
   Also anything after a = can be a type, if it is not an inline declaration "record ... end", "(enum)", "0..9", ... then it is a typename and should be highlighted.
   e.g. type TFoo = OtherUnit.TheFooType;
- In a var/const block it is similar but after the colon.
- Same in function parameter lists (declaration).


Now in code it is way more complex.
  A := THis.Meth();
THis could be a class (type). Or it could be a variable (object).
  B := Foo(1);
Function or typecast?

Not only does one need to know if there is a type THis or Foo. It is needed to know if this identifier is a type in this scope.
Code: Pascal  [Select]
  1. type Foo = Byte;
  2. procedure Bar;
  3.   procedure Foo(a: integer); begin end;
  4. begin
  5.   x := Foo(1);
  6. end;
There is a type Foo. But above code refers to the function.

Yes all this can be determined. In fact codetools already do this.
The best way to go about this would be a TSynEditMarkup module.





In the HL look at
 TSynPasSyn.IdentKind
TSynPasSyn.NExt

and
cfbtVarType, cfbtLocalVarType

as well as
    rsAfterEqualOrColon,   // very first word after "=" or ":"
    rsAfterEqual,          // between "=" and ";" (or block end) // a ^ means ctrl-char, not pointer to type


An ident after a equal or colon, if inside a vartype block.....


I need to spent a bit more time for more info.

Also not sure, if it should at all go into the HL (it can for a personal mod). Because for future extension it may be better as a markup module. (But that needs a lot more explanation than I could write up right now)




Btw to understand how HL do work, read https://wiki.lazarus.freepascal.org/SynEdit_Highlighter
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 08:09:20 pm
Quote
Now in code it is way more complex.
  A := THis.Meth();
THis could be a class (type). Or it could be a variable (object).
  B := Foo(1);
Function or typecast?

Thx first of all, for the huge interest in my issue :)

2.) But I really need to rely on lazarus/FPC naming convinctions (any type has a "T" prefix) so if you have code like: "Foo(x)" I will treat it as ur fault, if you dont mark it as TFoo (as it should be) and if its an external class, u can make it urself (but i saw like 90%code is reliant on the type convections, so no worries about this)
Same goes for "THis.Meth(), i need to rely on the naming convections, like variables never should be declared with an uppercase, so i will assume any variable is written in lowercase, so with this assumption it can work well and to be fair, i dont make excusive-assumptions here but anythign else is generally bad code desing, in tgerms of names, so I will like color the usual and good naming rules :-D

Whats ur opinion on it Martin
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 08:14:19 pm
Ahhh and btw thx for the link to understand the ighlighter  :D :P

Title: Re: Sourcecodeeditor typecolor customization
Post by: Martin_fr on November 18, 2019, 08:30:10 pm
2.) But I really need to rely on lazarus/FPC naming convinctions (any type has a "T" prefix) so if you have code like: "Foo(x)" I will treat it as ur fault, if you dont mark it as TFoo (as it should be) and if its an external class, u can make it urself (but i saw like 90%code is reliant on the type convections, so no worries about this)

For your own personal use, you can of course rely on the T.

For an official add on to the IDE, things should work for any name.

- Integer (not a build in type, the build in is afaik longint) does not have a T.
- English words can start with a T. A variable "There" could be a type "T Here". (Yes upper/lower....)


If you want to base this on a regex like pattern, to find identifiers starting with a T, then  TSynEditMarkupHighlightAllCaret or its base class is a good starting point. Make a copy, and instead of searching for a specific word search for words starting with T.
But that is not going to be an official patch.... (and not working for the windows unit, that has afaik lots of types not starting with a T)

ide/SynSourceEditor shows how to activate the new markup.


Title: Re: Sourcecodeeditor typecolor customization
Post by: howardpc on November 18, 2019, 08:33:21 pm
"Relying on Lazarus/FPC naming conventions" is almost guaranteed not to work consistently unless you are restricting your project to code you write and control yourself.
For a start, Lazarus and FPC sources do not follow the same conventions, and neither set of sources is particularly self-consistent.
This is perfectly understandable - there is no one policing the code, except that new code might be rejected simply on stylistic grounds, even if it were perfect in every other respect. Over the years there have been numerous contributors, each with his own style preferences, which may not bend too much towards the preferred house style when coded in anger. The hundreds of thousands of lines of legacy code are not going to be rewritten to conform to some ideal any time soon.
For instance FPC source often uses capitalised identifiers for variables. While classes usually tend to start with a "T" many other types do not, quite apart from all the non-"T" standard types such as Byte, Boolean, Pointer etc.
Consistent highlighting has to rely on in-depth parsing that has accurately determined the syntactic meaning. It cannot depend on 'surface' formatting or conventional leading characters being present.
Title: Re: Sourcecodeeditor typecolor customization
Post by: Martin_fr on November 18, 2019, 08:35:26 pm
Just for info. Markup is an extension to highlighting.

The highlighter is bound to the language (usually structure, and lexical stuff, but NO content parsing).
So the pascal HL gets all the blocks (begin/end/var/class/....), and lexical stuff like numbers, ";" ":=", or strings....


Markups are usually not language specific. Though there are several (FoldColorOutline, LowLightIfdef, WordPairs) that are specific to either one HL, or a group of HL.

Markups can scan for anything. There are no limiting rules. But of course they must be fast enough to be called on each paint of the editor..


To get the final result, the editor first gets the color from the HL, then asks every Markup for any changes to that color, and then paints it.
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 09:06:10 pm
@Martin_fr

So i really need only to watch out for:

Quote
TSynPasSyn.IdentKind
TSynPasSyn.NExt

and
cfbtVarType, cfbtLocalVarType

as well as
    rsAfterEqualOrColon,   // very first word after "=" or ":"
    rsAfterEqual,          // between "=" and ";" (or block end) // a ^ means ctrl-char, not pointer to type


An ident after a equal or colon, if inside a vartype block.....
?

So I can write my code logic inside the "IdentToken" and "Next" functions/procedures  based on the "=" after/before part ypu have mentioned?
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 09:21:04 pm
But I have to be honest, i am currently heavily engaged in working on GameEngine stuff and improving their, so no real time for this, i thought this could be a bit faster, but I saw its not haha.

Anyways maybe its smth for you guys, since it would be a really nice feature , it helps alot visually to distinguish code, would be glad to see it in next or future patches :)

Title: Re: Sourcecodeeditor typecolor customization
Post by: Tz on November 18, 2019, 09:27:14 pm
At last,  Personally I like this feature.

Make pairing clear

I just add UInt8 UInt16 UInt32 UInt64 Int8 Int16 Int32 Int64 Single Double Extended Currency DateTime Guid
Bytes String Object Array Boolean Byte Char WideChar AnsiString WideString UnicodeString

example code

Code: Pascal  [Select]
  1.   TJSON = class (TObject)
  2.   public
  3.     const
  4.     EmptyObject = '{}';
  5.   private
  6.     FObject   :TJSONObject;
  7.     procedure Add(APath :String; AData :TJSONData);
  8.     function  GetAJSON  :String;
  9.     procedure SetAJSON    (AData :String);
  10.     function  GetBoolean  (APath :String) :Boolean;
  11.     function  GetUInt8    (APath :String) :UInt8;
  12.     function  GetUInt16   (APath :String) :UInt16;
  13.     function  GetUInt32   (APath :String) :UInt32;
  14.     function  GetUInt64   (APath :String) :UInt64;
  15.     function  GetInt8     (APath :String) :Int8;
  16.     function  GetInt16    (APath :String) :Int16;
  17.     function  GetInt32    (APath :String) :Int32;
  18.     function  GetInt64    (APath :String) :Int64;
  19.     function  GetSingle   (APath :String) :Single;
  20.     function  GetDouble   (APath :String) :Double;
  21.     function  GetExtended (APath :String) :Extended;
  22.     function  GetCurrency (APath :String) :Currency;
  23.     function  GetDateTime (APath :String) :TDateTime;
  24.     function  GetGuid     (APath :String) :TGuid;
  25.     function  GetBytes    (APath :String) :TBytes;
  26.     function  GetString   (APath :String) :String;
  27.     function  GetObject   (APath :String) :String;
  28.     procedure SetBoolean  (APath :String; AData :Boolean);
  29.     procedure SetUInt8    (APath :String; AData :UInt8);
  30.     procedure SetUInt16   (APath :String; AData :UInt16);
  31.     procedure SetUInt32   (APath :String; AData :UInt32);
  32.     procedure SetUInt64   (APath :String; AData :UInt64);
  33.     procedure SetInt8     (APath :String; AData :Int8);
  34.     procedure SetInt16    (APath :String; AData :Int16);
  35.     procedure SetInt32    (APath :String; AData :Int32);
  36.     procedure SetInt64    (APath :String; AData :Int64);
  37.     procedure SetSingle   (APath :String; AData :Single);
  38.     procedure SetDouble   (APath :String; AData :Double);
  39.     procedure SetExtended (APath :String; AData :Extended);
  40.     procedure SetCurrency (APath :String; AData :Currency);
  41.     procedure SetDateTime (APath :String; AData :TDateTime);
  42.     procedure SetGuid     (APath :String; AData :TGuid);
  43.     procedure SetBytes    (APath :String; AData :TBytes);
  44.     procedure SetString   (APath :String; AData :String);
  45.     procedure SetObject   (APath :String; AData :String);
  46.   public
  47.     constructor Create;
  48.     destructor Destroy; override;
  49.     function AsFormat                   :String;
  50.     property AsJSON                     :String     read GetAJSON     write SetAJSON;
  51.     property AsBoolean  [APath :String] :Boolean    read GetBoolean   write SetBoolean;
  52.     property AsUInt8    [APath :String] :UInt8      read GetUInt8     write SetUInt8;
  53.     property AsUInt16   [APath :String] :UInt16     read GetUInt16    write SetUInt16;
  54.     property AsUInt32   [APath :String] :UInt32     read GetUInt32    write SetUInt32;
  55.     property AsUInt64   [APath :String] :UInt64     read GetUInt64    write SetUInt64;
  56.     property AsInt8     [APath :String] :Int8       read GetInt8      write SetInt8;
  57.     property AsInt16    [APath :String] :Int16      read GetInt16     write SetInt16;
  58.     property AsInt32    [APath :String] :Int32      read GetInt32     write SetInt32;
  59.     property AsInt64    [APath :String] :Int64      read GetInt64     write SetInt64;
  60.     property AsSingle   [APath :String] :Single     read GetSingle    write SetSingle;
  61.     property AsDouble   [APath :String] :Double     read GetDouble    write SetDouble;
  62.     property AsExtended [APath :String] :Extended   read GetExtended  write SetExtended;
  63.     property AsCurrency [APath :String] :Currency   read GetCurrency  write SetCurrency;
  64.     property AsDateTime [APath :String] :TDateTime  read GetDateTime  write SetDateTime;
  65.     property AsGuid     [APath :String] :TGuid      read GetGuid      write SetGuid;
  66.     property AsBytes    [APath :String] :TBytes     read GetBytes     write SetBytes;
  67.     property AsString   [APath :String] :String     read GetString    write SetString;
  68.     property AsObject   [APath :String] :String     read GetObject    write SetObject;
  69.     property AsArray    [APath :String] :String     read GetObject    write SetObject;
  70.   end;
  71.  
  72.  

 :)
Title: Re: Sourcecodeeditor typecolor customization
Post by: Martin_fr on November 18, 2019, 09:27:56 pm
Yes it will be a bit of work.

For adding this to the HL, yes those are the functions to start with...

Also maybe FTokenIsCaseLabel, which does the highlight mod for case labels, and then in the mentioned locations a FTokenIsTypeName would need to be added.


On the long term, I think this will however go into a markup (or half and half...) .... Because then it can later be extended with codetools.
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 18, 2019, 10:31:36 pm
@Martin_fr

so you would consider the effort to implement this (as I said, its smth all IDE have nowadays) ?

Since I cant put the effort right now fior this as I mentioned before, maybe some other lazarus-users have interesst in this :)
Title: Re: Sourcecodeeditor typecolor customization
Post by: Martin_fr on November 19, 2019, 12:11:13 am
You are not the first to ask for this....
And in general this is an acceptable feature request.

As for when and who....

This depends a lot on time available. I currently maintain SynEdit and the IDE-Debugger (including all the backend-wrappers: gdb-wrapperS, lldb-wrapper, fpdebug). This is taking huge amounts of time. So I can make no promise when (or if) I will get to work on it.

Adding colors, in the var/const/param blocks only (excluding any code blocks), is probably something I can do in reasonable time. I am not sure if it's worth it. The real usefulness of highlighting the types is if they occur inside the code block.
For the code block part, there is no way around code-tools (and probably added caching). However with Codetools I am not that familiar, so that will take considerable longer.
Title: Re: Sourcecodeeditor typecolor customization
Post by: Shpend on November 19, 2019, 02:50:56 pm
@Martin_fr:

Ofc, I can understand this fully, as I mentioned earlier, I am engaged currently myself in something also very time and brain consuming and I am not able to participate on it unfortunately, as much as I would like too actually, but Im still not such a good developer who can multi-task develop source code in different areas .

And yea, the stuff you mentioned have higher priority ofc, I want just to stretch again, that it is a nice feature an IDE should provide, its fully up to you guys, when you decide to implement it !


Anyway, thanks for taking the issue/request seriously and atleast considering it.

Title: Re: Sourcecodeeditor typecolor customization
Post by: Tz on November 26, 2019, 01:50:27 pm
Just add list for term _ (underscore) and ; (semicolon) with Money Green color

seem snake case more readable, and less noise.

My current scheme color is Delphi, but I think should be tune for each theme.

awesome  :D