Code::Blocks Forums

User forums => Using Code::Blocks => Topic started by: Immint on October 05, 2016, 01:43:24 am

Title: Open multiple files in Code::Blocks from the command line
Post by: Immint on October 05, 2016, 01:43:24 am
I'm very used to being able to easily open files from the command line in my favourite editor, and for multiple reasons this habit has become ingrained in my workflow. I'd like to be able to do this with Code::Blocks as well, but I'm running headfirst into a brick wall here. :-\

The help page for the executable offers the --file= command line option, but this only allows you to provide a single file. When adding the command line option twice, only the last file is opened. I could write a batch script to take all my command line arguments and run the codeblocks.exe executable for each separately. This works like a charm IFF Code::Blocks is already running. If a new instance has to be started, only the first file is opened... ???

Second, I noticed you can add multiple files on the commandline without --file=. This resulted in a very odd problem. If I open a file like this, then close it (the file; not Code::Blocks), then open another file, both files now get opened. If I close the two files and open a third file like this, Code::Blocks opens all three previously thusly-opened files! :o The only way to get Code::Blocks to forget about the files opened this way appears to be to completely close the program. Clearly this is not what I want either. :(

To add insult to injury, the Windows Explorer has no trouble doing what I want at all. Click single files, multiple files, it'll always open them correctly without re-opening previously opened files. Of course, in Windows 10, it seems entirely impossible to verify how the Explorer communicates with the programs it launches (or at least the option is very well hidden), so this doesn't help me at all. >:(

So to reiterate, here is the question:
How do I correctly open multiple files in Code::Blocks from the command line?

Thanks! :)
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: BlueHazzard on October 05, 2016, 07:49:19 pm
i am curious about your workflow... Are you using c::b as generic text editor? Or why do you want to open multiple source files without a project?
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: Immint on October 05, 2016, 10:20:28 pm
I do actually plan to use Code::Blocks as a generic text editor as well if it lets me (I already have it open and it's good at editing code; why not? :P) but the main reason I want to open files from the command line is because I use the command line to find the files I want to open in the first place, for example based on the diff between two git commits or a grep of the source tree, or because a ticket already includes a list of relevant files. This is true even when I'm working on a Code::Blocks project.

There are also many cases where I'm working on code that's not (only) mine, where I don't want to pollute my repository with a Code::Blocks project (which I then have to keep up to date if source files are added or removed by someone else that doesn't use Code::Blocks), or a project that's better compiled by makefiles, even if just because one already exists and I don't have the time to make a working .cbp file out of it, and I definitely don't want to maintain both a makefile and a Code::Blocks project file.

Anyway, that's all off-topic. I'd still like to have an answer to the question! :)
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: oBFusCATed on October 06, 2016, 01:19:56 am
Probably no one has tried it or used it in such a way. Patches welcome.
There were some other reports of this being broken, but I don't remember details. :(

To add insult to injury, the Windows Explorer has no trouble doing what I want at all. Click single files, multiple files, it'll always open them correctly without re-opening previously opened files. Of course, in Windows 10, it seems entirely impossible to verify how the Explorer communicates with the programs it launches (or at least the option is very well hidden), so this doesn't help me at all. >:(
I think it works using DDE https://msdn.microsoft.com/en-us/library/windows/desktop/ms632538(v=vs.85).aspx

p.s. cb supports makefile based projects...
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: Jenna on October 06, 2016, 08:52:24 am
I can confirm this.
C::B has a a list of files to be opened delayed.
My guess is, that the files are not removed from this loist, if they are opened.
I try to look into it.

I think it works using DDE https://msdn.microsoft.com/en-us/library/windows/desktop/ms632538(v=vs.85).aspx
and ipc on Linux, but he mechanism is (more or less) transparent inside C::B, because we use the wxWidgets implementation.
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: Immint on October 06, 2016, 10:56:47 pm
Thanks for the confirmation! This weekend I think I'll see if I can find where the list of files to be opened is stored and whether it's easy to empty it up once it's done loading files. It sounds like it should be doable to fix even without prior knowledge of the source code. Alternatively if I get stumped there, I could have a look into how the DDE communication works and write a little wrapper to start Code::Blocks or send files that way. Maybe wxWidgets even offers a way to tackle this for Windows and Linux simultaneously.
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: Jenna on October 07, 2016, 10:25:15 am
Thanks for the confirmation! This weekend I think I'll see if I can find where the list of files to be opened is stored and whether it's easy to empty it up once it's done loading files. It sounds like it should be doable to fix even without prior knowledge of the source code. Alternatively if I get stumped there, I could have a look into how the DDE communication works and write a little wrapper to start Code::Blocks or send files that way. Maybe wxWidgets even offers a way to tackle this for Windows and Linux simultaneously.
It's actually an issue in wxWidgets 2.8, which is fixed in wx3.
It was brought up by one of our developers and we most likely have a thread about it, but nevertheless I forgot it, sorry.

See: http://trac.wxwidgets.org/ticket/16503

In other words, it can not be fixed with wxWidgets 2.8 based C::B, but should not be present if build against wx3.
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: Immint on October 11, 2016, 01:05:04 am
After some tinkering, I managed to get the 64 bit version of Code::Blocks to compile against wxWidgets 3.1 into a working executable with corresponding set of dlls. :) Feels a bit different in a way I can't quite put my finger on, but I can confirm the weird starting problems are fixed. Thanks for the help, everybody! :D
Title: Re: Open multiple files in Code::Blocks from the command line
Post by: Immint on November 05, 2016, 01:10:18 am
Just a quick followup (much delayed because I had very little time to actually do any home coding lately)

After having some trouble with the wxWidgets 3 version I compiled, I decided to go another route and toy with DDE for a bit. I ended up writing a little launcher to do what I want. In case anyone runs into the same problem, here's the program in its entirety. You can compile it with any version of wxWidgets with any compiler and use it with any official binary of Code::Blocks; the library will see to it that the communication works correctly. :D

Code
#include <wx/app.h>
#include <wx/ipc.h>

wxString DdeServiceName(wxString UserId)
{
#ifdef __WXMSW__
    return "CODEBLOCKS";
#else
    return _T("/tmp/CODEBLOCKS") + UserId + _T(".socket");
#endif
}

class CbLauncherApp : public wxApp
{
    public:
        virtual bool OnInit();
};

IMPLEMENT_APP(CbLauncherApp);

bool CbLauncherApp::OnInit()
{
    wxLogNull ln; // We don't want visible errors on failed connections.

    wxClient client;
    wxConnection* connection = dynamic_cast<wxConnection*>(
        client.MakeConnection(_T("localhost"),
                              DdeServiceName(wxGetUserId().wx_str()),
                              _T("CodeBlocksDDEServer")));

    if (connection)
    {
        // We have a connection to an existing instance; send the file list...
        for (int i = 1 ; i < argc; ++i)
            connection->Execute(_T("[Open(\"") + argv[i] + _T("\")]"));
        // ...and raise the window to the top.
        connection->Execute(_T("[Raise]"));
        connection->Disconnect();
        delete connection;
    }
    else
    {
        // No running instance, so start a new one.
        wxString cmdLine;
        for (int i = 1 ; i < argc; ++i)
            cmdLine += _T(" \"") + wxString(argv[i]) + _T("\"");
        wxExecute(_T("codeblocks.exe") + cmdLine);
    }
    return false;
}

Note that it's very limited in what it does; you can't pass any commandline arguments to Code::Blocks after the first instance, and all paths must be absolute. Because it already does what I needed it to, I didn't develop it any further, but I still wanted to leave this here to not ultimately leave the question answered but the problem unsolved! :)