Recent

Author Topic: SynEdit highlighter attributes dynamically changing  (Read 8031 times)

staratel20

  • Full Member
  • ***
  • Posts: 218
SynEdit highlighter attributes dynamically changing
« on: March 21, 2016, 09:00:45 am »
Good day.

Analyze the code of [beautiful] example code '...\SynEdit\NewHighlighterTutorial\' I successfully write my own highlighter. But for my goal I need to dynamically change attributes of ONE highlighter (including Attribute.Name and Attribute.Caption). Fist I think it's very easy - I simple write something like:

Code: Pascal  [Select][+][-]
  1. MyHighlighter.Clear;

and again add needed attributes. But ... no method 'Clear' in TSynCustomHighlighter class. I try to modify unit SynEditHighlighter and add it method Clear:

Code: Pascal  [Select][+][-]
  1. procedure TSynCustomHighlighter.Clear;
  2. var
  3.   i:integer;
  4. begin
  5.   i:=0;
  6.   while(i<AttrCount)do
  7.   begin
  8.     fAttributes.Objects[i].Free;
  9.     fAttributes.Objects[i]:=nil;
  10.   inc(i);
  11.   end;
  12.   fAttributes.Clear;
  13. end;

I expect, that after call this method and then - MySynEdit.Update (or something) all will looks good, but it's don't.

Also want to notice, that would be intuitively if present method AddAttribute - than present also method DelAttribute. Absent of such method looks some weird.
« Last Edit: March 21, 2016, 09:22:41 am by staratel20 »
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: SynEdit highlighter attributes dynamically changing
« Reply #1 on: March 21, 2016, 08:38:42 pm »
I dont know what you want to archive, and if a highlighter is the best solution (there is an alternative concept called Markup).

Normally Attributes are typical to the structure of the document. So they never change. This is way there only is an Add method.

You can remove all of them by calling FreeHighlighterAttributes (usually done in Destroy)

Since adding is only expected during creation, and freeing only in destroy, neither of them will trigger any updates.


Reviewing the sample code, I found it has a bug. The following is missing (I will commit that asap to svn)

 
Code: Pascal  [Select][+][-]
  1.  // Ensure the HL reacts to changes in the attributes. Do this once, if all attributes are created
  2.   SetAttributesOnChange(@DefHighlightChange);
  3.  

If you add or remove attributes, then try to call
Code: Pascal  [Select][+][-]
  1.  DefHighlightChange();
that should trigger a rescan, and also get SynEdit to repaint.

staratel20

  • Full Member
  • ***
  • Posts: 218
Re: SynEdit highlighter attributes dynamically changing
« Reply #2 on: March 22, 2016, 07:28:40 am »
Quote
If you add or remove attributes, then try to call
but how can I remove attributes? In the class TSynCustomHighlighter is exist only method AddAttribute and I don't see something like Delete(IndexAttr:integer) or RemoveAttribute(IndexAttr:integer)

Also I think that in class TSynCustomHighlighter intuitively must to be exist method Clear(which means - delete all attributes).
« Last Edit: March 22, 2016, 12:51:39 pm by staratel20 »
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: SynEdit highlighter attributes dynamically changing
« Reply #3 on: March 22, 2016, 01:01:44 pm »
You can only remove all of them.

Well, maybe you can get away, and skip AddAttribute. You can then store them in your own List and have full control.

All the Attribute related functions are virtual, so you can override them as needed.

What are you trying to archive? Maybe there is another solution?

Edson

  • Hero Member
  • *****
  • Posts: 1325
Re: SynEdit highlighter attributes dynamically changing
« Reply #4 on: March 22, 2016, 03:26:44 pm »
FreeHighlighterAttributes, works well to delete all the attributes.

I would like to know too: Why would you need to delete an specific attribute?

Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

staratel20

  • Full Member
  • ***
  • Posts: 218
Re: SynEdit highlighter attributes dynamically changing
« Reply #5 on: March 22, 2016, 05:09:41 pm »
Edson: in my situation I need exactly - delete all attributes. Thank you for 'magic function' FreeHighlighterAttributes - exactly what I need. Honestly I ask myself - why not called simple - 'Clear' - first name the user(developer) will looking for, if will need to clear all attributes. And then, when not find - go to documentation(or forum) to discover FreeHighlighterAttributes )). In my inherited highlighter class I define method 'Clear' with only one instruction with this procedure.

Bay the way - think way not good to naming property AttrCount - CountAttr look more pretty. When user will writing some code and type dot(and helper list appeared) - no need to remember 'Count of what?' - enough to know that need 'count of something' , and when begin type 'count...' in helper list he see - 'of cause - CountAttr'. I use this naming rule all my life and it's very, very comfort to use. Maybe in Lazarus already exist another naming agreement(I don't know) - only say what I think to make Lazarus better.

Martin_fr: thank you for advises, but when I write finally code with Edson method it also work when I remove
Code: [Select]
SetAttributesOnChange(@DefHighlightChange);I don't know why but work).

Thanks for all your answers.

Oops, almost forgot...
Quote
I would like to know too: Why would you need to delete an specific attribute?
at this time I write search engine which will highlight founded words. So, what if you want to change background of word on mouse over? But really my task - absolutely not mater, as wrote Ray Konopka in his book(not pretend at quote): "You can't even imagine for which purpose user can use your component".
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

Edson

  • Hero Member
  • *****
  • Posts: 1325
Re: SynEdit highlighter attributes dynamically changing
« Reply #6 on: March 22, 2016, 05:53:40 pm »
Thank you for 'magic function' FreeHighlighterAttributes - exactly what I need.

In fact, that function was mentioned by Martin.

at this time I write search engine which will highlight founded words. So, what if you want to change background of word on mouse over?

I'm not sure, but I have the feeling this is a work for Markups.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

staratel20

  • Full Member
  • ***
  • Posts: 218
Re: SynEdit highlighter attributes dynamically changing
« Reply #7 on: March 22, 2016, 07:57:10 pm »
Quote
that function was mentioned by Martin
I'm also thanks to Martin. But function name some confused me, so I don't found at once.

Quote
I have the feeling this is a work for Markups
In future - maybe, who knows. But not this time. This time I need it for exactly what I'm wrote above.

Also want to ask - is exist easy way to modify my attached code to highlight not only whole words, but also a part of words. I look to example 'SynPositionHighlighter' and it's not looks simple. But if it simplest way - I'll go look further.

P/s: Also will glad to see this(or modified) code in repository examples if it needed. Think it easy as it can be.
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

Edson

  • Hero Member
  • *****
  • Posts: 1325
Re: SynEdit highlighter attributes dynamically changing
« Reply #8 on: March 22, 2016, 08:56:48 pm »
Also want to ask - is exist easy way to modify my attached code to highlight not only whole words, but also a part of words.

A highlighter "highlights" tokens. The rules to extract tokens, are defined in the highlighter. If your highlighter  includes the logic to recognize part of words like tokens, then it will highlight part of words.

I see in your code, an strange way to highlight words. You are creating an attribute for each word. Normally many words share the same attribute.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: SynEdit highlighter attributes dynamically changing
« Reply #9 on: March 23, 2016, 03:11:55 am »
I had a quick look at it. If I read it correctly, then what you try to do is similar to http://wiki.lazarus.freepascal.org/New_IDE_features_since#Multiple_user_defined_word_highlight.2Fmarkup
(And it can do partial words too)

Only that you will have an individual color for each word, instead of groups. And that would mean many instances of the markup, and be quite slow.

About your code:
Code: Pascal  [Select][+][-]
  1. function TFindContentHL.GetTokenAttribute: TSynHighlighterAttributes;
  2. ...
  3.   while(i<Self.AttrCount)do
  4.   begin
  5.     s:= LowerCase(Self.Attribute[i].Name);
  6.     sc:=LowerCase(copy(FLineText, FTokenPos,
  7.  
sc is the same in each iteration of the loop. So calculate it upfront.
Ideally use a binary search.

Or if you want to go for partial words anyway, copy and adapt

Or use TSynSearchDictionary from unit syneditmarkuphighall.pp
IIRC it uses https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm for the search. It can find any token, even as part of a word.

The Markup it that unit stores search results. That is only needed if words can match across line bounds. Otherwise you can scan each line on request.

staratel20

  • Full Member
  • ***
  • Posts: 218
Re: SynEdit highlighter attributes dynamically changing
« Reply #10 on: March 23, 2016, 08:19:47 am »
Thanks for replies. Now in thinking how to screw the wheels to all of that to make it go).
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

staratel20

  • Full Member
  • ***
  • Posts: 218
Re: SynEdit highlighter attributes dynamically changing
« Reply #11 on: March 25, 2016, 02:16:48 pm »
Let me ask one more thing... In Lazarus Aho-Corasick algorithm already implemented, or used more simple algorithm? And in which module it implemented(of cause I can found by myself, but maybe somebody remember it) ?
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: SynEdit highlighter attributes dynamically changing
« Reply #12 on: March 25, 2016, 04:30:43 pm »
Let me ask one more thing... In Lazarus Aho-Corasick algorithm already implemented, or used more simple algorithm?

 TSynSearchDictionary from unit syneditmarkuphighall.pp

It can still be optimized for memory footprint (if you have dictionaries with thousands of words). But it will work as it is, and it will be way better than stringlist.

staratel20

  • Full Member
  • ***
  • Posts: 218
Re: SynEdit highlighter attributes dynamically changing
« Reply #13 on: March 25, 2016, 07:07:39 pm »
Thank, I'll look there. So many new interesting information.
Windows 7 SP1 x64, FPC 3.0.0, Lazarus from trunk: http://svn.freepascal.org/svn/lazarus/trunk

CountIdentity, ModeClassName - good property naming
IdentityCount,  ClassNameMode  - bad property naming

 

TinyPortal © 2005-2018