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
37 changes: 6 additions & 31 deletions src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ App::~App()


void
App::Init()
App::Init(bool suppressWindow)
{
BPath settingsPath;
find_directory(B_USER_SETTINGS_DIRECTORY, &settingsPath);
Expand All @@ -88,6 +88,8 @@ App::Init()
EditorWindow::SetPreferences(fPreferences);

Languages::LoadLanguages();

fSuppressInitialWindow = suppressWindow;
}


Expand Down Expand Up @@ -200,36 +202,12 @@ App::QuitRequested()
void
App::ReadyToRun()
{
if(CountWindows() == 0 && fSuppressInitialWindow == false) {
if(fSuppressInitialWindow == false && CountWindows() == 0) {
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)
{
Expand All @@ -248,8 +226,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 +241,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: 1 addition & 3 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 @@ -38,12 +37,11 @@ class App : public BApplication {
App();
~App();

void Init();
void Init(bool suppressWindow);

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

Expand Down
170 changes: 116 additions & 54 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,137 @@

#include "App.h"

#include <string>

#include <Roster.h>

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

#include "EditorWindow.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;
}


void
_RunApp(bool suppressWindow)
{
App* app = new App();
app->Init(suppressWindow);
app->Run();
delete app;
}


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");
// start the app immediately if we're being launched from the GUI in case we need to handle
// an initial BMessage, otherwise the message will be lost when we Launch() in the background
if(isatty(STDOUT_FILENO) == 0) {
_RunApp(false);
return 0;
}

int option_index = 0;
struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"wait", no_argument, 0, 'w'},
{"launchkoderapp", 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, "launchkoderapp") == 0) {
_RunApp(true);
return 0;
}
return 1;
} break;
default:
_PrintUsage();
return 1;
}
}

if(waitForExit == true && argc - optind > 1) {
std::cerr << "Error: Only one filename allowed when using --wait." << 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;
if(waitForExit == true) {
windowMessage.what = WINDOW_NEW_WITH_QUIT_REPLY;
} else if(waitForExit == false && optind == argc) {
// no file arguments, open a blank window
windowMessage.what = WINDOW_NEW;
} else {
windowMessage.what = 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;
// always add column and line so that the count is the same as the number of refs
windowMessage.AddRef("refs", &ref);
windowMessage.AddInt32("be:column", column);
windowMessage.AddInt32("be:line", line);
}

return 0;
entry_ref appRef;
if(get_ref_for_path(argv[0], &appRef) != B_OK) {
std::cerr << "Error: Unable to determine Koder application path." << std::endl;
return 1;
}

BRoster roster;
team_id team;
const char* args[] = { "--launchkoderapp", nullptr };
// Use the entry_ref version of Launch() to make sure B_SINGLE_LAUNCH works correctly
status_t status = roster.Launch(&appRef, 1, args, &team);
if(status != B_OK && status != B_ALREADY_RUNNING) {
std::cerr << "Error: Unable to launch Koder." << std::endl;
return 1;
}

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

return 0;
}