Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 4 additions & 40 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ App::App()
fLastActiveWindow(nullptr),
fAppPreferencesWindow(nullptr),
fFindWindow(nullptr),
fPreferences(nullptr),
fSuppressInitialWindow(false)
fPreferences(nullptr)
{
}

Expand Down Expand Up @@ -197,44 +196,12 @@ App::QuitRequested()
}


void
App::ReadyToRun()
{
if(CountWindows() == 0 && fSuppressInitialWindow == false) {
PostMessage(WINDOW_NEW);
}
}


void
App::ArgvReceived(int32 argc, char** argv)
{
BMessage* message = CurrentMessage();
BString cwd = message->GetString("cwd", "~");
std::unique_ptr<BWindowStack> windowStack;
for(int32 i = 1; i < argc; ++i) {
std::string arg = argv[i];
// FIXME: this should be handled in main.cpp probably
if(arg == "-w" || arg == "--wait" || arg == "-h" || arg == "--help")
continue;
int32 line, column;
std::string filename = ParseFileArgument(argv[i], &line, &column);
if(filename.find('/') != 0) {
BPath absolute(cwd.String(), filename.c_str(), true);
filename = absolute.Path();
}
entry_ref ref;
BEntry(filename.c_str()).GetRef(&ref);
_ActivateOrCreateWindow(message, ref, line, column, windowStack);
}
}


void
App::RefsReceived(BMessage* message)
{
int32 count;
if(message->GetInfo("refs", nullptr, &count) != B_OK) {
PostMessage(WINDOW_NEW);
return;
}

Expand All @@ -248,8 +215,8 @@ App::RefsReceived(BMessage* message)
trackerMessage.AddRef("refs", &ref);
continue;
}
const int32 line = message->GetInt32("be:line", -1);
const int32 column = message->GetInt32("be:column", -1);
const int32 line = message->GetInt32("be:line", i, -1);
const int32 column = message->GetInt32("be:column", i, -1);
_ActivateOrCreateWindow(message, ref, line, column, windowStack);
}
}
Expand All @@ -263,9 +230,6 @@ void
App::MessageReceived(BMessage* message)
{
switch(message->what) {
case SUPPRESS_INITIAL_WINDOW: {
fSuppressInitialWindow = true;
} break;
case ACTIVATE_WINDOW: {
BWindow* window = nullptr;
if(message->FindPointer("window", (void**) &window) == B_OK && window != nullptr) {
Expand Down
4 changes: 0 additions & 4 deletions src/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class Styler;


enum {
SUPPRESS_INITIAL_WINDOW = 'Siwn',
WINDOW_NEW_WITH_QUIT_REPLY = 'NWwn',
ACTIVATE_WINDOW = 'actw'
};
Expand All @@ -42,8 +41,6 @@ class App : public BApplication {

void AboutRequested();
bool QuitRequested();
void ReadyToRun();
void ArgvReceived(int32 argc, char** argv);
void RefsReceived(BMessage* message);
void MessageReceived(BMessage* message);

Expand All @@ -67,7 +64,6 @@ class App : public BApplication {
Styler* fStyler;

BPath fPreferencesFile;
bool fSuppressInitialWindow;
};


Expand Down
149 changes: 94 additions & 55 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,114 @@

#include "App.h"

#include <string>

#include <Roster.h>

#include <iostream>
#include <getopt.h>

#include "Utils.h"


void
_PrintUsage()
{
std::cerr
<< "Usage: Koder [options] file..." << std::endl
<< "Options:" << std::endl
<< " -h, --help\t\tPrints this message." << std::endl
<< " -w, --wait\t\tWait for the window to quit before returning." << std::endl
<< "\t\t\tOpening in window stacks is not supported in this mode." << std::endl
<< "\t\t\tCurrently accepts only one filename." << std::endl;
}


int
main(int argc, char** argv)
{
std::string arg1 = argc > 1 ? argv[1] : "";
if(argc > 1 && (arg1 == "-h" || arg1 == "--help")) {
fprintf(stderr, "Usage: Koder [options] file...\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -h, --help\t\tPrints this message.\n");
fprintf(stderr, " -w, --wait\t\tWait for the window to quit before "
"returning.\n"
"\t\t\tOpening in window stacks is not supported in this mode.\n"
"\t\t\tCurrently accepts only one filename.\n");
int option_index = 0;
struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"wait", no_argument, 0, 'w'},
{"launch", no_argument, 0, 0},
{0, 0, 0, 0}};

bool waitForExit = false;
int c;
while((c = getopt_long(argc, argv, "hw", long_options, &option_index)) != -1) {
switch(c) {
case 'w': {
waitForExit = true;
} break;
case 'h': {
_PrintUsage();
return 1;
} break;
case 0: {
if(strcmp(long_options[option_index].name, "launch") != 0) {
return 1;
}
App* app = new App();
app->Init();
app->Run();
delete app;
return 0;
} break;
default:
_PrintUsage();
return 1;
break;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary break

}
}

if(waitForExit && argc - optind > 1) {
std::cerr << "Error: Only one filename allowed when launching in --wait mode." << std::endl;
return 1;
}

if(argc > 1 && (arg1 == "-w" || arg1 == "--wait")) {
if(argc > 3) {
fprintf(stderr, "Koder accepts only one filename when launching "
"in --wait mode.\n");
BMessage windowMessage(waitForExit ? (system_message_code) WINDOW_NEW_WITH_QUIT_REPLY : B_REFS_RECEIVED);
while(optind < argc) {
int32 line, column;
BPath filePath(ParseFileArgument(argv[optind++], &line, &column).c_str(), nullptr, true);
if(filePath.InitCheck() != B_OK) {
std::cerr << "Error: Invalid file path specified." << std::endl;
return 1;
}
BRoster roster;
team_id team = roster.TeamFor(gAppMime);
if(team == B_ERROR) {
BMessage* suppressMessage = new BMessage(SUPPRESS_INITIAL_WINDOW);
status_t status = roster.Launch(gAppMime, suppressMessage, &team);
delete suppressMessage;
if(status != B_OK && status != B_ALREADY_RUNNING) {
fprintf(stderr, "An issue occured while trying to launch Koder.\n");
return 1;
}

entry_ref ref;
BEntry entry(filePath.Path(), true);
if(entry.InitCheck() != B_OK || (entry.Exists() == true && entry.IsFile() == false)) {
std::cerr << "Error: Specified path is not a regular file." << std::endl;
return 1;
}
BMessage windowMessage(WINDOW_NEW_WITH_QUIT_REPLY);
// parse filename if any
// TODO: support -- for piping
if(argc > 2) {
int32 line, column;
std::string filename = ParseFileArgument(argv[2], &line, &column);
if(filename.find('/') != 0) {
BPath absolute(".", filename.c_str(), true);
filename = absolute.Path();
}
entry_ref ref;
BEntry(filename.c_str()).GetRef(&ref);
windowMessage.AddRef("refs", &ref);
if(line != -1) {
windowMessage.AddInt32("be:line", line);
}
if(column != -1) {
windowMessage.AddInt32("be:column", column);
}
if(entry.GetRef(&ref) != B_OK) {
std::cerr << "Error: Unable to get entry_ref for path." << std::endl;
return 1;
}
BMessenger messenger(gAppMime, team);
BMessage reply;
messenger.SendMessage(&windowMessage, &reply);
return 0;
} else {
App* app = new App();
app->Init();
app->Run();
delete app;

return 0;
windowMessage.AddRef("refs", &ref);
// always add column and line so that the count is the same as the number of refs
windowMessage.AddInt32("be:column", column == -1 ? 0 : column);
windowMessage.AddInt32("be:line", line == -1 ? 0 : line);
}

BEntry entry(argv[0], true);
entry_ref ref;
if(entry.InitCheck() != B_OK || entry.GetRef(&ref) != B_OK) {
std::cerr << "Error: Unable to determing Koder application path" << std::endl;
return 1;
}

const char* args[] = { "--launch", nullptr };
team_id team = -1;
// use the entry_ref version of Launch() to make sure B_SINGLE_LAUNCH works correctly
status_t status = be_roster->Launch(&ref, 1, args, &team);
if(status != B_OK && status != B_ALREADY_RUNNING) {
std::cerr << "An error occurred while trying to launch Koder." << std::endl;
return 1;
}

BMessenger messenger(gAppMime, team);
BMessage reply;
messenger.SendMessage(&windowMessage, &reply);

return 0;
}