Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-01

IDE package interface question

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Darius Blaszyk

Hi,

How can I get the source filename, method name and position on clicking the source editor through the ideintf? I would like to have this so I can make my IDE package (fpprofiler) context sensitive.

Regards, Darius

Darius Blaszyk
to Mattias Gaertner

What I would like to do is to update a listview (in my package) after I click on the source editor. So I need to hook into the source editor's OnClick method and get the procedure/function name, line number and the file name. The last two items will probably be more easy, but what about the first? Is there an interface for the code tools that allows this? How about hooking into the OnClick method of the source editor?

Regards, Darius

Mattias Gaertner wrote 20 lines
On Tue, 25 Jan 2011 00:23:44 +0100 Darius Blaszyk wrote: > Hi, > > How can I get the source filename, method name and position on clicking the source editor through the ideintf? I would like to have this so I can make my IDE package (fpprofiler) context sensitive. Source filename and position: http://wiki.lazarus.freepascal.org/Extending_the_IDE#Source_Editor What do you mean with method name? Of the identifier at cursor or the method name of the current method body? Mattias -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Mattias Gaertner
to Darius Blaszyk
What I would like to do is to update a listview (in my package) after I click on the source editor. So I need to hook into the source editor's OnClick method and get the procedure/function name, line number and the file name. The last two items will probably be more easy, but what about the first? Is there an interface for the code tools that allows this? How about hooking into the OnClick method of the source editor?

With OnClick I guess you mean left click?
Why only update on click?
Why not update after every cursor movement on a second idle?

About method name:
maybe you mean something like ide/codetemplatesdl.pas function CodeMacroProcedureHead.

Mattias

Darius Blaszyk
to Mattias Gaertner
Mattias Gaertner wrote 8 lines
On Tue, 25 Jan 2011 00:51:07 +0100 Darius Blaszyk wrote: > What I would like to do is to update a listview (in my package) after I click on the source editor. So I need to hook into the source editor's OnClick method and get the procedure/function name, line number and the file name. The last two items will probably be more easy, but what about the first? Is there an interface for the code tools that allows this? How about hooking into the OnClick method of the source editor? With OnClick I guess you mean left click? Why only update on click? Why not update after every cursor movement on a second idle?

You're right, it should be on every cursor movement. So how can I trigger the update when the cursor moves? I had a look at the wiki, but the code did not give any hints on that as far as I could see.

About method name: maybe you mean something like ide/codetemplatesdl.pas function CodeMacroProcedureHead.

Thanks, will have a look.

Darius

Martin
to Darius Blaszyk: What I would like to do is to update a listview (in my package) after I click on the…
Darius Blaszyk wrote
What I would like to do is to update a listview (in my package) after I click on the source editor. So I need to hook into the source editor's OnClick method and get the procedure/function name, line number and the file name. The last two items will probably be more easy, but what about the first? Is there an interface for the code tools that allows this? How about hooking into the OnClick method of the source editor?

Well first, you need to be aware, that SourceEditors (SynEdit), and SourceNotebook(s) ( the windows in which they are) can come and fo.

Your start-point is TSourceEditorManagerInterface in ideintf\srceditorintf.pas

     procedure RegisterChangeEvent(AReason: TsemChangeReason; AHandler:
TNotifyEvent); virtual; abstract;
     procedure UnRegisterChangeEvent(AReason: TsemChangeReason;
AHandler: TNotifyEvent); virtual; abstract;

To allow you keep track of them.

Be aware "semEditorStatus" will fire a hell lot. not the best Idea to use it. (it will fire on every caret move for example); unfortunately not on click (unless the click moves the caret, but that isn't always the case. => For status change, it is better to register with synedit direct, since you can give synedit a filter, and reduce the amount of calls, to what you need.

Since SynEdit's on click will already be hooked, that want be easy.... Actually, just seen it isn't; but it could any day.

You could register your own mouse action with SynEdit, but that's rather complex too.
It would be enough to register a proc with
SynEdit.RegisterMouseActionSearchHandler, or
TSynEditMouseActionExecProc. It would receive the mouse info, but could just do nothing (unless you want to abort the current action. However:
- I am not 100% sure that will stay exactly as it is. e.g in user land synedit this may become an optional handler. in the IDE it is 99.99% likely to stay as it is.
- There is no grantee on the calling order, other handlers could return true first, and yours would not be called

--------------------
At this point I noticed your next post.

RegisterStatusChangedHandler in synedit => see what fpdoc edit does

Martin
to Martin
Martin wrote 5 lines
-------------------- At this point I noticed your next post. RegisterStatusChangedHandler in synedit => see what fpdoc edit does

ide\fpdoceditwindow.pas

line 297

Darius Blaszyk
to Martin: Well first, you need to be aware, that SourceEditors (SynEdit), and SourceNotebook(s) (…

Martin / Mattias,

Thanks for the help. I finally used RegisterChangeEvent and it works fine. Unfortunately I have a another problem now. After modifying the caret position the event is fired and from the caret position I need to resolve the method name. I have looked at how this is done ./examples/idequickfix, but unfortunately whatever I try ProcNode keeps returning nil. The snippet below is from the above mentioned example but slightly modified. To view the code in context see here: http://svn.freepascal.org/cgi-bin/viewvc.cgi/fpprofiler/trunk/lazprof/lazprofview.pas?view=markup&revision=2525&root=fpcprojects. Can someone help me here please?

Thanks in advance,

Darius

  AUnit := SourceEditorManagerIntf.ActiveSourceWindow.ActiveEditor.FileName;
  DebugLn('TLazProfileViewer.ShowCodeInfo - 1');
  if AUnit  CachedUnit then
  begin
    if Assigned(CodeBuf) then
      FreeAndNil(CodeBuf);
    //load the unit file
    CodeBuf := CodeToolBoss.LoadFile(AUnit, False, False);
    DebugLn('TLazProfileViewer.ShowCodeInfo - 2');
    // parse the code
    if not ParseCode(CodeBuf, CodeTool) then
      exit;
    DebugLn('TLazProfileViewer.ShowCodeInfo - 3');
  end;
  Pos := SourceEditorManagerIntf.ActiveSourceWindow.ActiveEditor.CursorTextXY;
  DebugLn('TLazProfileViewer.ShowCodeInfo - 4');
  //find the source position
  if not CaretToSourcePosition(CodeTool, CodeBuf, Pos.x, Pos.y, CleanPos) then
    exit;
  DebugLn('TLazProfileViewer.ShowCodeInfo - 5');
  // find procedure node
  ProcNode := CodeTool.FindDeepestNodeAtPos(CleanPos, False);
  if ProcNode  nil then
    ProcNode := ProcNode.GetNodeOfType(ctnProcedure);
  DebugLn('TLazProfileViewer.ShowCodeInfo - 6');
  //nothing found so exit
  if ProcNode = nil then
     exit;
Mattias Gaertner
to Darius Blaszyk
Show quoted text 15 lines
Martin / Mattias, Thanks for the help. I finally used RegisterChangeEvent and it works fine. Unfortunately I have a another problem now. After modifying the caret position the event is fired and from the caret position I need to resolve the method name. I have looked at how this is done ./examples/idequickfix, but unfortunately whatever I try ProcNode keeps returning nil. The snippet below is from the above mentioned example but slightly modified. To view the code in context see here: http://svn.freepascal.org/cgi-bin/viewvc.cgi/fpprofiler/trunk/lazprof/lazprofview.pas?view=markup&revision=2525&root=fpcprojects. Can someone help me here please? Thanks in advance, Darius AUnit := SourceEditorManagerIntf.ActiveSourceWindow.ActiveEditor.FileName; DebugLn('TLazProfileViewer.ShowCodeInfo - 1'); if AUnit CachedUnit then begin

Maybe the above if is the cause. Remove it.

if Assigned(CodeBuf) then FreeAndNil(CodeBuf);

Do not free what you have not created. This will crash the IDE.

//load the unit file CodeBuf := CodeToolBoss.LoadFile(AUnit, False, False);
if CodeBuf=nil then exit;
Show quoted text 29 lines
DebugLn('TLazProfileViewer.ShowCodeInfo - 2'); // parse the code if not ParseCode(CodeBuf, CodeTool) then exit; DebugLn('TLazProfileViewer.ShowCodeInfo - 3'); end; Pos := SourceEditorManagerIntf.ActiveSourceWindow.ActiveEditor.CursorTextXY; DebugLn('TLazProfileViewer.ShowCodeInfo - 4'); //find the source position if not CaretToSourcePosition(CodeTool, CodeBuf, Pos.x, Pos.y, CleanPos) then exit; DebugLn('TLazProfileViewer.ShowCodeInfo - 5'); // find procedure node ProcNode := CodeTool.FindDeepestNodeAtPos(CleanPos, False); if ProcNode nil then ProcNode := ProcNode.GetNodeOfType(ctnProcedure); DebugLn('TLazProfileViewer.ShowCodeInfo - 6'); //nothing found so exit if ProcNode = nil then exit;

Mattias

Unknown author
to Mattias Gaertner
Mattias Gaertner wrote
> if AUnit CachedUnit then > begin Maybe the above if is the cause. Remove it.

I found the problem. The line and column number were switched. Therefore CleanPos was bogus.

Now one last problem, how to find the method name? ProcNode.DescAsString allways gves me "Procedure". Do I need to search for another NodeType or use some other method of TCodeTreeNode?

Regards, Darius

Mattias Gaertner
to Unknown author
Show quoted text 13 lines
On Mon, 31 Jan 2011 23:35:11 +0100, Mattias Gaertner wrote: >> if AUnit CachedUnit then >> begin > > Maybe the above if is the cause. Remove it. I found the problem. The line and column number were switched. Therefore CleanPos was bogus. Now one last problem, how to find the method name? ProcNode.DescAsString allways gves me "Procedure". Do I need to search for another NodeType or use some other method of TCodeTreeNode?
CodeTool.ExtractProcHead(ProcNode,Attributes);

Mattias