eranif / codelite

A multi purpose IDE specialized in C/C++/Rust/Python/PHP and Node.js. Written in C++
https://codelite.org
GNU General Public License v2.0
2.08k stars 444 forks source link

Need help creating codlelite Plugin #3368

Open noeldiviney opened 1 month ago

noeldiviney commented 1 month ago

I am using codelite version 17.10.0 on Linux Mint 21.2.. Creating a Plugin with Wizard Plugin as described in the Documentation is now working. I notice that the version of codelite used in the Documentation is version 5.4 which is no longer available for download.

All help appreciated

NoelDiviney

eranif commented 1 month ago

Hi Noel, later tonight I will send you a plugin skeleton

noeldiviney commented 1 month ago

Hello Eran, Many thanks, the help is appreciated. I am working on STM32 Embedded Development using Codelite. Progress so far is to use Stm32CubeMX as a External Tool to create a CMake Project. I will send you some screenshots in due course.

Cheers Noel.

eranif commented 1 month ago

Hey, in order to create a plugin, follow these simple steps:

Code completion tip:

Once CMake execution is completed, copy compile_commands.json from the build directory (for me its usually build-release or build-debug) to the root folder of CodeLite sources and restart clangd ( from within CodeLite hit: Ctrl-Shift-P and then type Restart language server)

MyPlugin.zip

Jarod42 commented 1 month ago

Code completion tip:

Or adjust Language Server settings for clangd, especially --compile-commands-dir ;-)

eranif commented 1 month ago

Usually I create a symlink to the compile_commands.json -> build-release/compile_commands.json file

noeldiviney commented 1 month ago

Hello Eran,

Success!!!. I am now able to create Plugins (see screenshots below)

The challenge now id to turn the Plugins into making them do something useful. Do you have a suggestion as to which existing Plugin I could use as a guide?.

A big thank you Noel.

CodeliteESD JtagitPA

eranif commented 1 month ago

This depends on what your plugin does.

Lets say that your plugin is expected to do something during the build (F7). There are 3 events that you can work with:

/// Sent just before the build starts.  You can override the default build behavior here by NOT calling event.Skip()
wxEVT_BUILD_STARTING
/// The build has started 
wxEVT_BUILD_STARTED
/// The build has ended
wxEVT_BUILD_ENDED

In your plugin constructor add these lines:

EventNotifier::Get()->Bind(wxEVT_BUILD_STARTING, &MyPlugin::OnBuildStarting, this);
EventNotifier::Get()->Bind(wxEVT_BUILD_STARTED, &MyPlugin::OnBuildStarted, this);
EventNotifier::Get()->Bind(wxEVT_BUILD_ENDED, &MyPlugin::OnBuildEnded, this);

In the UnPlug method:

EventNotifier::Get()->Unbind(wxEVT_BUILD_STARTING, &MyPlugin::OnBuildStarting, this);
EventNotifier::Get()->Unbind(wxEVT_BUILD_STARTED, &MyPlugin::OnBuildStarted, this);
EventNotifier::Get()->Unbind(wxEVT_BUILD_ENDED, &MyPlugin::OnBuildEnded, this);

And finally, add these 3 methods:

void MyPlugin::OnBuildStarting(clBuildEvent& event)
{
    // This event is sent using EventNotifier::Get()->ProcessEvent, i.e. CodeLite will not continue
    // until all plugins will reply with "event.Skip(true)"

    // If we call event.Skip(true) here, this event will be propagated to other plugins
    // If all other plugis called "event.Skip(true)", then CodeLite will continue with 
    // the default build process. The first plugin that does not call "event.Skip()" (or called
    // event.Skip(false)) will stop the event from propagating and CodeLite assumes that a plugin took
    // over the build and it will not trigger the default build process

    // NOTE: calling event.Skip(false) is equal to NOT calling event.Skip() at all
    // So basically, we could replace the default build behavior here by adding this lines:

    event.Skip(false);                  // I'm taking over this event - so do not start the default process
    ::wxExecute("my-build-script.sh");  // Run some random code instead
}

void MyPlugin::OnBuildStarted(clBuildEvent& event)
{
    // This event is sent using EventNotifier::Get()->AddPendingEvent, i.e. it is for notifcation only
    // We must call event.Skip(true) to make sure that other plugins will get this event as well
    event.Skip(true);
}

void MyPlugin::OnBuildEnded(clBuildEvent& event)
{
    // We must call event.Skip(true) to make sure that other plugins will get this event as well
    event.Skip(true);
}

See this file: https://github.com/eranif/codelite/blob/master/CodeLite/codelite_events.h For all supported event types (there are over 200 event types)

So the approach is: find the event you want to interact with, search it in CodeLite code base for reference

See the Rust plugin for example: Rust plugin

noeldiviney commented 1 month ago

Thanks Eran, I will be using a stm32F411CEU6 MCU CMakeLists.txt which requires the appending of lines before the build. I will now go away and read up on your suggestions as well as trying out some code experiments to gain some more experience. Manny thanks for the advice. I will keep you posted on progress.

Cheers Noel

noeldiviney commented 1 month ago

Hi Eran.

I am developing OpenOCD Programming adapter GUI using Codelite/wxCrafter called jtagitPA I need to be able to get user password input to install tools and setup linux. See attached Screenshots below.

Running the jtagitPA GUI as a External Tool Plugin I can see the output on the Codelite Output Pane. So any suggestions on being able to input my password?.

If I run jtagitPA GUI from a terminal I am able to enter the password and execute the bash scripts

Any help woul be great.

Noel.

Codelite-jtagitPA-ExternalTool jtagitPA-run-from-terminal esdev-lin .sh.tar.gz

noeldiviney commented 1 month ago

Oops!! missing the External Tool screenshop Codelite-jtagitPA-ExternalTool

Noel

eranif commented 1 month ago

This could be a bit tricky as you need a "real" terminal for this. I would take a different approach: Instead of using sudo I would use sudo -A this will invoke the UI (usually ssh-askpass)

noeldiviney commented 1 month ago

Thanks Eran. I will give it a try and let you know later. Noel

noeldiviney commented 1 month ago

I am having difficulty setting up linux to get sudo -A working. However I have managed to get the Bash script to run using the command "username ALL = (ALL) NOPASSWD: ALL". I have to enter my username password to get this to work. There seems to be a number of ways to get "sudo -A" to work but I have not figured how yet.

Also I could mimic what happens when I run the GUI from a terminal by having the GUI launch a background Console but so far no joy with that. I am able to get this method to work if I use wxPython.

The other approach I have tried is to change IMPLEMENT_APP(MainApp) to IMPLEMENT_APP_CONSOLE(MainAPP), but that does not attach a terminal to allow the password to be entered.

Any suggestions appreciated.

Noel.