Recent

Author Topic: [SOLVED] TSynEdit Code Completion Opening at position in Editor  (Read 1290 times)

zxandris

  • Full Member
  • ***
  • Posts: 170
[SOLVED] TSynEdit Code Completion Opening at position in Editor
« on: February 17, 2024, 11:59:34 am »
Hi there, I've mostly worked out how to use code completion in SynEdit, but for some reason just pressing CTRL+Space didn't work, I would assume because I'm controlling my own key down event's, so that's okay I figured out how to invoke the code completion okay, but now with the code below it only opens at the mouse pointer, I was wondering if there's a way to figure out the location on the screen the caret is and open it there?

Any help would be appreciated.  I have...

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.synEditKeyDown(Sender: TObject; var Key: Word;
  2.   Shift: TShiftState);
  3. var
  4.       pnt : TPoint;
  5.       startPos, endPos, a, len : Integer;
  6.       txt, str : STring;
  7. begin
  8.      if synEdit.Modified then FModified := true;
  9.      if (key=32) then
  10.      begin
  11.           if ssCTRL in shift then
  12.           begin
  13.               endPos := synEdit.CaretX;
  14.               txt := synEdit.Lines[SynEdit.CaretY-1];
  15.               str := '';
  16.               for a := endPos downto 0 do
  17.               begin
  18.                   if (txt[a] = ' ') or (txt[a]= #10) or (a<=0) then
  19.                   begin
  20.                       startpos := a+1;
  21.                       len := endPos - StartPos;
  22.                       str := Copy(txt, startPos, len);
  23.                       str := trim(str);
  24.                   end;
  25.               end;
  26.               pnt := mouse.CursorPos;
  27.               if str<>'' then
  28.                  SynCompletion.Execute(str, pnt.x, pnt.y);
  29.           end;
  30.      end;
  31. end;
  32.  
« Last Edit: February 18, 2024, 08:36:11 am by zxandris »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12612
  • Debugger - SynEdit - and more
    • wiki
Re: TSynEdit Code Completion Opening at position in Editor
« Reply #1 on: February 17, 2024, 12:05:24 pm »
Code: Pascal  [Select][+][-]
  1. pnt := ClientToScreen(Point(SynEdit.CaretXPix, SynEdit.CaretYPix + SynEdit.LineHeight + 1));

zxandris

  • Full Member
  • ***
  • Posts: 170
Re: TSynEdit Code Completion Opening at position in Editor
« Reply #2 on: February 17, 2024, 12:32:55 pm »
That's cool but it's a lilttle off, I think because my synEdit isn't in the top left of the screen.  Is there a way to get the top left of a control and then I can perhaps work from there.  Thanks for the help so far, I feel like such a noob :).

zxandris

  • Full Member
  • ***
  • Posts: 170
Re: TSynEdit Code Completion Opening at position in Editor
« Reply #3 on: February 17, 2024, 12:52:00 pm »
I'm getting closer, but I can't quite tell what I'm missing, would someone mind logic checking for me.  It's nearly there, and honestly I can't quite tell why it's not right just using CaretYPix, etc.

Code: Pascal  [Select][+][-]
  1.  
  2. procedure TfrmMain.synEditKeyDown(Sender: TObject; var Key: Word;
  3.   Shift: TShiftState);
  4. var
  5.       pnt, ctl : TPoint;
  6.       startPos, endPos, a, t, l, len : Integer;
  7.       txt, str : STring;
  8. begin
  9.      if synEdit.Modified then FModified := true;
  10.      if (key=32) then
  11.      begin
  12.           if ssCTRL in shift then
  13.           begin
  14.               t := synEdit.top;
  15.               if pnlProject.visible then
  16.                  l := pnlProject.width + synEdit.Left
  17.               else l := synEdit.left;
  18.               ctl.x := t;
  19.               ctl.y := l;
  20. //              ctl := ClientToScreen(ctl);
  21.               endPos := synEdit.CaretX;
  22.               txt := synEdit.Lines[SynEdit.CaretY-1];
  23.               str := '';
  24.               for a := endPos downto 0 do
  25.               begin
  26.                   if (txt[a] = ' ') or (txt[a]= #10) or (a<=0) then
  27.                   begin
  28.                       startpos := a+1;
  29.                       len := endPos - StartPos;
  30.                       str := Copy(txt, startPos, len);
  31.                       str := trim(str);
  32.                   end;
  33.               end;
  34.               pnt.x := synEdit.CaretXPix + ctl.X;
  35.               pnt.y := synEdit.CaretYPix + (synEdit.LineHeight * (synEdit.CaretY))+1;
  36.               pnt := ClientToScreen(pnt);
  37. //              pnt := ClientToScreen(Point((SynEdit.CaretXPix + ctl.x), (SynEdit.CaretYPix) + (SynEdit.LineHeight + 1)+ctl.y));
  38.               //pnt := mouse.CursorPos;
  39.               if str<>'' then
  40.                  SynCompletion.Execute(str, pnt.x, pnt.y);
  41.           end;
  42.      end;
  43.      inherited;
  44. end;
  45.  
  46.  

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12612
  • Debugger - SynEdit - and more
    • wiki
Re: TSynEdit Code Completion Opening at position in Editor
« Reply #4 on: February 17, 2024, 02:13:41 pm »
Code: Pascal  [Select][+][-]
  1. SynEdit.ClientToScreen()

And then don't add ctl.x.

Every control has its own ClientToScreen => and it already takes the coordinates of the control within the form into account.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12612
  • Debugger - SynEdit - and more
    • wiki
Re: TSynEdit Code Completion Opening at position in Editor
« Reply #5 on: February 17, 2024, 02:18:33 pm »
Not directly related to your issue, but important info on SynEdit => especially if you edit text via code

https://wiki.freepascal.org/SynEdit#Logical.2FPhysical_caret_position
https://wiki.freepascal.org/SynEdit#Change_text_from_code

zxandris

  • Full Member
  • ***
  • Posts: 170
Re: TSynEdit Code Completion Opening at position in Editor
« Reply #6 on: February 18, 2024, 07:27:28 am »
Thanks guys, this is the corrected code just in case anyone else has a similiar issue and it'll help them.

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.synEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  2. var
  3.       pnt : TPoint;
  4.       startPos, endPos, a, len, sp : Integer;
  5.       txt, str : STring;
  6. begin
  7.      if synEdit.Modified then FModified := true;
  8.      if (key=32) then
  9.      begin
  10.           if ssCTRL in shift then
  11.           begin
  12.               endPos := synEdit.CaretX;
  13.               sp := synEdit.SelStart;
  14.               txt := synEdit.Lines[SynEdit.CaretY-1];
  15.               str := '';
  16.               // Work out the string to search
  17.               for a := endPos downto 0 do
  18.               begin
  19.                   if (txt[a] = ' ') or (txt[a]= #10) or (a<=0) then
  20.                   begin
  21.                       startpos := a+1;
  22.                       len := endPos - StartPos;
  23.                       str := Copy(txt, startPos, len);
  24.                       str := trim(str);
  25.                       break;
  26.                   end;
  27.               end;
  28.               // Select the text
  29.               synEdit.SelStart := sp - length(str);
  30.               synEdit.SelEnd := synEdit.SelStart + length(str);
  31.               // Calculate the complete box position
  32.               pnt.x := synEdit.CaretXPix + 5;
  33.               pnt.y := synEdit.CaretYPix;
  34.               pnt := synEdit.ClientToScreen(pnt);
  35.               // Show the box, if str<>''
  36.               if str<>'' then
  37.                  SynCompletion.Execute(str, pnt.x, pnt.y);
  38.           end;
  39.      end;
  40.      inherited;
  41. end;
  42.  

Modified: to remove unneeded var's and points, and it now selects the relevant text

Code: Pascal  [Select][+][-]
  1. SynEdit.ClientToScreen()

And then don't add ctl.x.

Every control has its own ClientToScreen => and it already takes the coordinates of the control within the form into account.

« Last Edit: February 18, 2024, 08:35:08 am by zxandris »

 

TinyPortal © 2005-2018