Search code examples
delphisynedit

How to handle links on Synedit tablenames?


I am working on a Sql editor, using TSynEdit in Delphi. I have my Object names (tables, stored procedures, domains and so on) in the Tablenames of the highlighter and Autocompletion, they show up in blue and underlined which is what i wanted but i wonder if i can make these linked to a event where i can actually open that object.

Is there a way to

a) Change the cursor to handPoint when mouse is over such keyword?

b) Execute a event, procedure, function when clicking on such keyword?

Thanks for any advice.

enter image description here


Solution

  • For getting mouse pointed token information you can write e.g. helper methods like this:

    type
      TSynEditHelper = class helper for TSynEdit
      public
        function GetTokenInfo(const CursorPos: TPoint; out TokenType: Integer; out TokenText: UnicodeString): Boolean; overload;
        function GetTokenInfo(const LineCharPos: TBufferCoord; out TokenType: Integer; out TokenText: UnicodeString): Boolean; overload;
      end;
    
    { TSynEditHelper }
    
    function TSynEditHelper.GetTokenInfo(const CursorPos: TPoint; out TokenType: Integer; out TokenText: UnicodeString): Boolean;
    begin
      Result := GetTokenInfo(DisplayToBufferPos(PixelsToRowColumn(CursorPos.X, CursorPos.Y)), TokenType, TokenText);
    end;
    
    function TSynEditHelper.GetTokenInfo(const LineCharPos: TBufferCoord; out TokenType: Integer; out TokenText: UnicodeString): Boolean;
    var
      I: Integer;
      A: TSynHighlighterAttributes;
    begin
      Result := GetHighlighterAttriAtRowColEx(LineCharPos, TokenText, TokenType, I, A);
    end;
    

    And use them in the OnMouseCursor for setting the cursor and OnClick for keyword navigation:

    procedure TForm1.SynEdit1Click(Sender: TObject);
    var
      TokenType: Integer;
      TokenText: UnicodeString;
    begin
      if TSynEdit(Sender).GetTokenInfo(TSynEdit(Sender).ScreenToClient(Mouse.CursorPos), TokenType, TokenText) and
        (TokenType = Ord(tkTableName)) then
      begin
        ShowMessage(Format('Table token clicked: %s', [TokenText]));
      end;
    end;
    
    procedure TForm1.SynEdit1MouseCursor(Sender: TObject; const ALineCharPos: TBufferCoord; var ACursor: TCursor);
    var
      TokenType: Integer;
      TokenText: UnicodeString;
    begin
      if TSynEdit(Sender).GetTokenInfo(ALineCharPos, TokenType, TokenText) and (TokenType = Ord(tkTableName)) then
        ACursor := crHandPoint;
    end;
    

    I couldn't find a native way for this feature.