Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistent argument parsing #5189

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
9 changes: 5 additions & 4 deletions doc/kak.1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
.Op Fl ui Ar ui_type
.Op Fl e Ar command
.Op Fl E Ar command
.Op Sy + Ns Ar line Ns Oo Sy \&: Ns Ar column Oc | Sy +:
.Op Sy + Ns Oo Ns Ar line Oc | Sy + Ns Ar line Ns Sy \&: Ns Oo Ns Ar column Oc
.Op Fl Fl
.Op Ar file ...
.
.Nm
Expand Down Expand Up @@ -151,10 +152,10 @@ Begin in
.Em readonly mode ,
all the buffers opened will not be written to disk.
.
.It Sy + Ns Ar line Ns Oo Sy \&: Ns Ar column Oc | Sy +:
.It Sy + Ns Oo Ns Ar line Oc | Sy + Ns Ar line Ns Sy \&: Ns Oo Ns Ar column Oc
Specify a target line and column for the first file.
When the plus sign is followed by only a colon, then the cursor is sent
to the last line of the file.
When the line is omitted the cursor will go to the end of the buffer.
When colon is present but the column is omitted the cursor will got to the end of the given line.
.
.It Ar file ...
One or more
Expand Down
51 changes: 10 additions & 41 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1102,18 +1102,17 @@ int main(int argc, char* argv[])
{ "debug", { ArgCompleter{}, "initial debug option value" } },
{ "version", { {}, "display kakoune version and exit" } },
{ "ro", { {}, "readonly mode" } },
{ "help", { {}, "display a help message and quit" } } }
{ "help", { {}, "display a help message and quit" } } },
ParameterDesc::Flags::WithCoord
};

try
{
auto show_usage = [&]() {
write_stdout(format("Usage: {} [options] [file]... [+<line>[:<col>]|+:]\n\n"
write_stdout(format("Usage: {} [options] [+[line] | +line:[column]] [--] [file]...\n\n"
"Options:\n"
"{}\n"
"Prefixing a positional argument with a plus (`+`) sign will place the\n"
"cursor at a given set of coordinates, or the end of the buffer if the plus\n"
"sign is followed only by a colon (`:`)\n",
"You can specify the initial position of the cursor using +[line] or +line:[column].\n",
argv[0], generate_switches_doc(param_desc.switches)));
return 0;
};
Expand All @@ -1122,9 +1121,6 @@ int main(int argc, char* argv[])
| transform([](auto* s) { return String{s}; })
| gather<Vector<String>>();

if (contains(params, "--help"_sv))
return show_usage();

ParametersParser parser{params, param_desc};

const bool show_help_message = (bool)parser.get_switch("help");
Expand Down Expand Up @@ -1185,32 +1181,8 @@ int main(int argc, char* argv[])
parser.get_switch("i").value_or(StringView{}));
}

Vector<StringView> files;
Optional<BufferCoord> init_coord;
for (auto& name : parser)
{
if (not name.empty() and name[0_byte] == '+')
{
if (name == "+" or name == "+:")
{
client_init = client_init + "; exec gj";
continue;
}
auto colon = find(name, ':');
if (auto line = str_to_int_ifp({name.begin()+1, colon}))
{
init_coord = std::max<BufferCoord>({0,0}, {
*line - 1,
colon != name.end() ?
str_to_int_ifp({colon+1, name.end()}).value_or(1) - 1
: 0
});
continue;
}
}

files.emplace_back(name);
}
auto init_coord = parser.get_coord();
auto files = parser | gather<Vector<StringView>>();

if (auto server_session = parser.get_switch("c"))
{
Expand All @@ -1222,14 +1194,11 @@ int main(int argc, char* argv[])
return -1;
}
}

String new_files;
for (auto name : files) {
new_files += format("edit '{}'", escape(real_path(name), "'", '\''));
if (init_coord) {
new_files += format(" {} {}", init_coord->line + 1, init_coord->column + 1);
init_coord.reset();
}
new_files += ";";
for (auto file : files)
{
new_files += format("edit -- '{}'\n", escape(real_path(file), "'", '\''));
}

return run_client(*server_session, {}, new_files + client_init, init_coord, ui_type, false);
Expand Down
20 changes: 20 additions & 0 deletions src/parameters_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& de
const bool switches_only_at_start = desc.flags & ParameterDesc::Flags::SwitchesOnlyAtStart;
const bool ignore_unknown_switches = desc.flags & ParameterDesc::Flags::IgnoreUnknownSwitches;
bool only_pos = desc.flags & ParameterDesc::Flags::SwitchesAsPositional;
bool with_coord = desc.flags & ParameterDesc::Flags::WithCoord;

Vector<bool> switch_seen(desc.switches.size(), false);
for (size_t i = 0; i < params.size(); ++i)
Expand All @@ -40,6 +41,25 @@ ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& de
m_state = State::Switch;
only_pos = true;
}
else if (not only_pos and with_coord and not params[i].empty() and params[i][0_byte] == '+')
{
m_state = State::Switch;
with_coord = false;
const auto coord_str = params[i].substr(1_byte);
const auto colon = find(coord_str, ':');

const auto line_str = StringView{coord_str.begin(), colon};
const LineCount line = line_str.empty() ? INT_MAX : std::max(1, str_to_int(line_str)) - 1;

ByteCount column = 0;
if (colon != coord_str.end())
{
const auto column_str = StringView{colon + 1, coord_str.end()};
column = column_str.empty() ? INT_MAX : std::max(1, str_to_int(column_str)) - 1;
}

m_coord = BufferCoord{line, column};
}
else if (not only_pos and not params[i].empty() and params[i][0_byte] == '-')
{
StringView switch_name = params[i].substr(1_byte);
Expand Down
6 changes: 5 additions & 1 deletion src/parameters_parser.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "hash_map.hh"
#include "meta.hh"
#include "array_view.hh"
#include "coord.hh"
#include "optional.hh"
#include "flags.hh"
#include "string.hh"
Expand Down Expand Up @@ -62,7 +63,8 @@ struct ParameterDesc
None = 0,
SwitchesOnlyAtStart = 0b0001,
SwitchesAsPositional = 0b0010,
IgnoreUnknownSwitches = 0b0100
IgnoreUnknownSwitches = 0b0100,
WithCoord = 0b1000,
};
friend constexpr bool with_bit_ops(Meta::Type<Flags>) { return true; }

Expand Down Expand Up @@ -142,12 +144,14 @@ struct ParametersParser
iterator end() const { return iterator(*this, m_positional_indices.size()); }

State state() const { return *m_state; }
Optional<BufferCoord> get_coord() const { return m_coord; }

private:
ParameterList m_params;
Vector<size_t, MemoryDomain::Commands> m_positional_indices;
HashMap<String, StringView> m_switches;
Optional<State> m_state;
Optional<BufferCoord> m_coord;
};

}
Expand Down