fxos/shell/p.cpp

214 lines
4.5 KiB
C++

#include "shell.h"
#include "parser.h"
#include "commands.h"
#include <fxos/project.h>
#include <fxos/util/log.h>
#include <fmt/core.h>
//---
// pn
//---
struct _pn_args
{
std::string name = "";
std::string path = "";
};
static struct _pn_args parse_pn(Session &, Parser &parser)
{
_pn_args args;
if(!parser.at_end())
args.name = parser.symbol("project");
if(!parser.at_end())
args.path = parser.str();
parser.end();
return args;
}
void _pn(Session &session, std::string const &name, std::string const &path)
{
if(!session.confirmProjectUnload())
return;
session.switchToNewProject(name, path);
if(path != "") {
session.project()->save();
session.recentProjects().touch(*session.project());
}
}
//---
// pr
//---
static std::string parse_pr(Session &, Parser &p)
{
std::string sym = p.symbol("");
p.end();
return sym;
}
void _pr(Session &session, std::string const &new_name)
{
Project *p = session.project();
if(!p)
return;
p->setName(new_name);
p->setDirty();
}
//---
// ps
//---
static std::string parse_ps(Session &, Parser &p)
{
std::string path;
if(!p.at_end())
path = p.str();
p.end();
return path;
}
void _ps(Session &session, std::string const &new_path)
{
Project *p = session.project();
if(!p) {
FxOS_log(ERR, "No current project o(x_x)o");
return;
}
if(new_path == "" && !p->canSave()) {
FxOS_log(ERR, "Project “%s” has no path; use ps with a path.",
p->name().c_str());
}
if(new_path != "")
p->setPath(new_path);
if(!p->save())
return;
session.recentProjects().touch(*p);
}
//---
// pm
//---
static std::string parse_pm(Session &, Parser &p)
{
std::string sym = p.symbol("vspace_name");
p.end();
return sym;
}
void _pm(Session &session, std::string const &legacy_vspace_name)
{
// TODO: pm
fmt::print("TODO: migrate {} to current project", legacy_vspace_name);
}
//---
// pl
//---
struct _pl_args
{
bool isRecent;
std::string source;
};
static struct _pl_args parse_pl(Session &, Parser &p)
{
struct _pl_args args;
if(p.lookahead().type == T::STRING) {
args.isRecent = false;
args.source = p.str();
}
else {
args.isRecent = true;
args.source = p.symbol("project");
}
p.end();
return args;
}
void _pl(Session &session, bool isRecent, std::string const &source)
{
if(!session.confirmProjectUnload())
return;
if(isRecent) {
std::string path = session.recentProjects().pathFromName(source);
if(path == "") {
FxOS_log(
ERR, "No recent project named “%s”; see ip.", source.c_str());
return;
}
if(session.loadProject(path))
session.recentProjects().touch(*session.project());
}
else {
if(session.loadProject(source))
session.recentProjects().touch(*session.project());
}
}
static ShellCommand _pn_cmd(
"pn",
[](Session &s, Parser &p) {
auto args = parse_pn(s, p);
_pn(s, args.name, args.path);
},
[](Session &s, Parser &p) { parse_pn(s, p); }, "Project New", R"(
pn [<name> ["<path>"]]
Switch a new empty project. If name is not specified, a default is used. If
path is not specified, it will need to be set in the first call to ps when
attempting to save.
)");
static ShellCommand _pr_cmd(
"pr", [](Session &s, Parser &p) { _pr(s, parse_pr(s, p)); },
[](Session &s, Parser &p) { parse_pr(s, p); }, "Project Rename", R"(
pr <name>
Changes the display name of the current troject.
)");
static ShellCommand _ps_cmd(
"ps", [](Session &s, Parser &p) { _ps(s, parse_ps(s, p)); },
[](Session &s, Parser &p) { parse_ps(s, p); }, "Project Save", R"(
ps ["<path>"]
Save the current project. If a folder is specified, save as a new folder.
)");
static ShellCommand _pm_cmd(
"pm", [](Session &s, Parser &p) { _pm(s, parse_pm(s, p)); },
[](Session &s, Parser &p) { parse_pm(s, p); }, "Project Migrate", R"(
pm <vspace_name>
Migrates a legacy virtual space from before version 1.x into the current
project as a new binary. Legacy virtual spaces can be listed with ip.
)");
static ShellCommand _pl_cmd(
"pl",
[](Session &s, Parser &p) {
auto args = parse_pl(s, p);
_pl(s, args.isRecent, args.source);
},
[](Session &s, Parser &p) { parse_pl(s, p); }, "Project Load", R"(
pl (<name> | "<path>")
Load a recent project by name or load a project from a folder.
)");