Recent

Author Topic: Synedit SynCompletion question/problem  (Read 5853 times)

snorkel

  • Hero Member
  • *****
  • Posts: 793
Synedit SynCompletion question/problem
« on: October 08, 2012, 08:02:17 pm »
Hi,
I am trying to get the stock synedit component to pop up the completion dialog when the user types a . (dot) for PostgreSQL schema completion.
For example if the user types SFT.  I want the completion box to contain all the tables, functions etc that are part of the schema "SFT"

So far I came up with this in the ProcessCommand event

procedure Tquery_editor.editorProcessCommand(Sender: TObject;
  var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
begin

       if achar = '.' then
           SynCompletion1.Execute('',editor.LogicalToPhysicalPos(editor.CaretXY));
end;

I thought this would work, but the completion window pops up in the upper left corner of the screen.

 any ideas?
***Snorkel***
If I forget, I always use the latest stable 32bit version of Lazarus and FPC. At the time of this signature that is Laz 1.8 and FPC 3.0.4
OS: Windows 10 64 bit

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5631
    • wiki
Re: Synedit SynCompletion question/problem
« Reply #1 on: October 08, 2012, 08:34:10 pm »
Execute takes pixel coordinates, relative to desktop/screen.

SynEdit.ClientToScreen(SynEdit.RowColumnToPixels(P));

where P is a point with physical coordinates

editor.CaretXY  is already physical, so no need to convert.
LogicalCaretXY is not (obviously) and neither are BlockBegin or BlockEnd

For info on logical/physical see http://forum.lazarus.freepascal.org/index.php/topic,18478.msg104341.html#msg104341

snorkel

  • Hero Member
  • *****
  • Posts: 793
Re: Synedit SynCompletion question/problem
« Reply #2 on: October 08, 2012, 09:47:59 pm »
Thanks Martin,

I came up with this which seems to work:

procedure Tquery_editor.editorProcessCommand(Sender: TObject;
  var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
var
   apoint,temppoint:tpoint;
   schema_tablename:string;
begin

       if achar = '.' then
        begin
             schema_tablename:=editor.GetWordAtRowCol(editor.CaretXY);
//will compare the schema_tablename to a list of available schema names for the current database.
             temppoint:=editor.CaretXY;
             temppoint.y:=temppoint.y+1;
             apoint:= editor.ClientToScreen(Editor.RowColumnToPixels(temppoint));
             SynCompletion1.Execute('',apoint);
        end;
end;

After playing around with this it does seem that I will need a timer for when the user types the .

Any suggestions on how to implement that?  Could I just use the standard system timer component?

***Snorkel***
If I forget, I always use the latest stable 32bit version of Lazarus and FPC. At the time of this signature that is Laz 1.8 and FPC 3.0.4
OS: Windows 10 64 bit

snorkel

  • Hero Member
  • *****
  • Posts: 793
Re: Synedit SynCompletion question/problem
« Reply #3 on: October 08, 2012, 10:03:58 pm »
Martin,
Have you ever looked at porting just the Delphi 2.x synedit completion proposal component to the Lazarus Synedit?
Seems the big area where Laz Synedit is lacking is in the completion department.

I am trying to get a handle on the Laz synedit internals, but it's difficult as the IDE does not use the stock components but implements a bunch of stuff on
it's own.

I'm bogged down trying to port my app to Lazarus, but if I have time I might try and port some of the Delphi Synedit completion proposal stuff, starting with the timer.
***Snorkel***
If I forget, I always use the latest stable 32bit version of Lazarus and FPC. At the time of this signature that is Laz 1.8 and FPC 3.0.4
OS: Windows 10 64 bit

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5631
    • wiki
Re: Synedit SynCompletion question/problem
« Reply #4 on: October 08, 2012, 10:08:15 pm »
       if achar = '.' then
technically, you should also test for aCommand = ecChar. Though aChar can not be '.' unless it is ecChar.

Quote

             schema_tablename:=editor.GetWordAtRowCol(editor.CaretXY);
GetWordAtRowCol is locical. Use editor.LogicalCaretXY

Quote
After playing around with this it does seem that I will need a timer for when the user types the .

Any suggestions on how to implement that?  Could I just use the standard system timer component?

Yes just the standard timer.

Make sure to cancel it on
- focus lost
- other keypress
- caret move (use Editor.OnStatusChange, it has a reason that can be inspected)

I have not tested your code, I do not know, if calling completion.execute BEFORE the editor handles the char may cause an issue.
There is
Code: [Select]
    procedure RegisterCommandHandler(AHandlerProc: THookedCommandEvent;
      AHandlerData: pointer; AFlags: THookedCommandFlags = [hcfPreExec, hcfPostExec]);
    procedure UnregisterCommandHandler(AHandlerProc: THookedCommandEvent);
which allows to register a handler at different times during processing.

Code: [Select]
RegisterCommandHandler(@YourHandler, nil, [hcfFinish]);
will run AFTER SynEdit completely finished with the command

YourHandle must be
Code: [Select]
THookedCommandEvent = procedure(Sender: TObject; AfterProcessing: boolean;
    var Handled: boolean; var Command: TSynEditorCommand;
    var AChar: TUTF8Char;
    Data: pointer; HandlerData: pointer) of object;

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5631
    • wiki
Re: Synedit SynCompletion question/problem
« Reply #5 on: October 08, 2012, 10:12:30 pm »
Martin,
Have you ever looked at porting just the Delphi 2.x synedit completion proposal component to the Lazarus Synedit?
Seems the big area where Laz Synedit is lacking is in the completion department.
Someone ported the entire 2.0.5 http://wiki.lazarus.freepascal.org/SynEdit#Synedit_2.0.5_port

The entire completion in SynEdit is currently way back. Too much other work. (You see: completion works well in the IDE. It is just hard to use outside...)

Quote
I am trying to get a handle on the Laz synedit internals, but it's difficult as the IDE does not use the stock components but implements a bunch of stuff on
it's own.

I'm bogged down trying to port my app to Lazarus, but if I have time I might try and port some of the Delphi Synedit completion proposal stuff, starting with the timer.
You are welcome, and you can ask question.