Author Topic: Plugin scripts - accessing local context data  (Read 14900 times)

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Plugin scripts - accessing local context data
« on: December 06, 2011, 04:54:07 am »
Hi, I'm new to the forums and to the internals of C::B, so please forgive my ignorance...

I'm read through the wiki pages on writing plugin scripts, and this appears to be a very powerful tool. The wiki explains enough for me to modify the menus and add context menus. Could anyone help me go further by giving a demonstration of how to do the following within a script?

Say I have some code in the currently open editor panel:
Code
// ...
a= foo(data);
//...

I'd like to be able to right-click within the word "foo" and get a context menu entry "change foo to bar", and if I select this entry the code would change to:
Code
// ...
a= bar(data);
//...

Can the above be done, and if so, how. Clearly the work should be done from GetModuleMenu(who, data), but I don't know how to access the string located under the cursor.

I've many more questions, but this would be a great start.


Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Plugin scripts - accessing local context data
« Reply #1 on: December 06, 2011, 10:43:27 am »
See the cbDebuggerPlugin::GetEditorWordAtCaret c++ function in http://svn.berlios.de/wsvn/codeblocks/branches/wxpropgrid_debugger/src/sdk/cbplugin.cpp?peg=7625
And then try to implement it in the script, if some of the methods/functions are missing we can expose them to the scripts.
This is the most clever version of the function and it does more than what you want.

Looking here wiki.codeblocks.org/index.php?title=Scripting_commands it seems that the cbStyleTextCtrl is missing from the binding.
I guess you can try to add the bindings yourself and then send us a patch, because I think I don't have time to do it now. It should be pretty easy, look at the wiki for the documentation of the process.

http://wiki.codeblocks.org/index.php?title=Script_bindings

If you have problems don't hesitate to ask.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

zabzonk

  • Guest
Re: Plugin scripts - accessing local context data
« Reply #2 on: December 06, 2011, 10:49:21 am »
Where would the context menu get "bar" from so it can say "change foo to bar"? Also, this feature kind of exists already in the Code Refactoring context menu.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Plugin scripts - accessing local context data
« Reply #3 on: December 06, 2011, 11:32:18 am »
Neil: The function I've posted does this - it is used in debugger's branch to get a string for the watches and why do you think he wants to implement refactoring tool in script?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #4 on: December 06, 2011, 12:25:47 pm »
oBFusCATed: Thanks, I'll look into that. I've just been using the 10.05 binary, but I shall have to be brave and start looking at the source. Looks like the more that can be exposed to scripting the better. Experience has taught me not to jump straight to C++ each time, fun though it is, and the scripting functionality has the potential to be very powerful.

Neil: My example wasn't for refactoring. I'm currently playing around with different approaches to unit testing and I was thinking about how to adding some tools for this. However, at present I'm just trying to understand what can be done. The point was to be able to get the content at the cursor position and change it, without a specific application intended. For this example bar could be hard-coded, foo should not.

However, taking things further, any idea how much harder would it be to identify which namespace/class/method I was currently in? The code completion toolbar appears to be able to do this...

Thank again.
« Last Edit: December 08, 2011, 11:15:23 am by beldaz »

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #5 on: December 08, 2011, 08:23:44 am »
Out of interest, GetEditorWordAtCaret makes no use of member data (The only thing accessed is Manager::Get(), which is a global or singleton, I think), so it would be better off as a non-member function. Maybe it would be better to expose a library of such useful functions, rather than (or in addition to) an additional class (cbStyleTextCtrl).

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Plugin scripts - accessing local context data
« Reply #6 on: December 08, 2011, 10:32:35 am »
Yes, I have the same idea, just have to implement it:)
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #7 on: December 08, 2011, 11:08:06 am »
:-)

Well, I'm up for getting involved in pulling out this particular function and working from there, so maybe I can help. I've struggled to compile C::B from source properly yet (my poor little netbook is puffing along trying to compile the wxWidgets library for about the 3rd time after numerous problems), so hopefully I'll be able to contribute soon...

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #8 on: December 10, 2011, 03:17:42 am »
Neil: You mentioned a code refactoring menu. I wanted to look at what this did, but couldn't see it in the SVN trunk. Could you point me to it?

[EDIT]: Found it within the code completion plugin code.
« Last Edit: December 11, 2011, 10:47:51 am by beldaz »

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #9 on: December 12, 2011, 11:29:17 am »
[...]

Looking here it seems that the cbStyleTextCtrl is missing from the binding.
I guess you can try to add the bindings yourself and then send us a patch, because I think I don't have time to do it now. It should be pretty easy, look at the wiki for the documentation of the process.

http://wiki.codeblocks.org/index.php?title=Script_bindings

If you have problems don't hesitate to ask.

I've had a go at adding appropriate bindings for cbStyleTextCtrl. The trouble is that the GetSelectedText method that I'm interested in is inherited from wxScintilla, which does not have the copy assignment operator required by the binding. For cbStyleTextCtrl I just followed the example of cbEditor and provided a not-to-use assignment method that calls cbThrow, but it would take a very ugly hack to do this within wxScintilla. Any suggestions? Perhaps there's a way to bind an inherited method without providing a binding to the base class (crossing fingers...).

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #10 on: December 13, 2011, 12:13:21 am »
Perhaps answering my own question, following the related wiki advice on overloaded functions, this seems to compile:

Code
typedef wxString(cbStyledTextCtrl::*cbStyledTextCtrlFunc)();

SqPlus::SQClassDef<cbStyledTextCtrl>("cbStyledTextCtrl")
    .func(&cbStyledTextCtrl::IsCharacter, "IsCharacter")
    .func(&cbStyledTextCtrl::IsString, "IsString")
    .func(&cbStyledTextCtrl::IsPreprocessor, "IsPreprocessor")
    .func(&cbStyledTextCtrl::IsComment, "IsComment")
    .func<cbStyledTextCtrlFunc>(&cbStyledTextCtrl::GetSelectedText, "GetSelectedText");

Now to see whether this actually works in a script...

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Plugin scripts - accessing local context data
« Reply #11 on: December 13, 2011, 10:32:45 am »
You have to bind cbEditor::GetControl probably and then use it to get the cbStyledTextCtrl.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #12 on: December 13, 2011, 12:09:03 pm »
You have to bind cbEditor::GetControl probably and then use it to get the cbStyledTextCtrl.
Already had that elsewhere, should have mentioned, sorry. The problem I was facing was a compilation one - SqPlus didn't like my adding bindings to members inherited from a base class (wxScintilla) for which there was no binding. And adding a binding for wxScintilla was not going to be easy. Explicitly defining the template parameters for the binding seems to fix this.

I've submitted patch (number 3242).

This patch provides bindings to all the cbStyledTextCtrl methods used in your cbDebuggerPlugin::GetEditorWordAtCaret method, and in a rather similar method CodeRefactoring::GetSymbolUnderCursor() in the code completion plugin. The one omission is cbStyledTextCtrl::PositionFromPoint, which takes a wxPoint value as a parameter. A binding for this breaks the build as the line "DECLARE_INSTANCE_TYPE(wxPoint)" in sc_base_type.h generates Match and Get functions only for passing by reference or pointer. I am open to suggestions as to how best to resolve this issue.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Plugin scripts - accessing local context data
« Reply #13 on: December 13, 2011, 12:33:45 pm »
This patch provides bindings to all the cbStyledTextCtrl methods used in your cbDebuggerPlugin::GetEditorWordAtCaret method, and in a rather similar method CodeRefactoring::GetSymbolUnderCursor() in the code completion plugin. The one omission is cbStyledTextCtrl::PositionFromPoint, which takes a wxPoint value as a parameter. A binding for this breaks the build as the line "DECLARE_INSTANCE_TYPE(wxPoint)" in sc_base_type.h generates Match and Get functions only for passing by reference or pointer. I am open to suggestions as to how best to resolve this issue.
You can bind a normal function with explicit this parameter, which uses reference instead of pointer parameters.

Something like:
Code
void my_method(MyClass *this, const Test &t) { this->my_method(&t); }
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline beldaz

  • Multiple posting newcomer
  • *
  • Posts: 20
Re: Plugin scripts - accessing local context data
« Reply #14 on: December 14, 2011, 11:01:56 am »
You can bind a normal function with explicit this parameter, which uses reference instead of pointer parameters.

Something like:
Code
void my_method(MyClass *this, const Test &t) { this->my_method(&t); }
Thanks for that. It wasn't quite what I needed, but close enough to put me on the right track (overloaded method with pass-by-reference shim.

Patch updated.