From 385a1aec188b3e4f827fb0ae358bc11787b30135 Mon Sep 17 00:00:00 2001 From: Philipp Jungkamp Date: Sun, 16 Jun 2024 14:48:37 +0200 Subject: [PATCH 1/4] Show `[--]` in `-help` output The current help output of kakoune doesn't mention that a double dash (`--`) can be used to separate the files from options. --- src/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cc b/src/main.cc index 0c63403bd..d340ba7ec 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1108,7 +1108,7 @@ int main(int argc, char* argv[]) try { auto show_usage = [&]() { - write_stdout(format("Usage: {} [options] [file]... [+[:]|+:]\n\n" + write_stdout(format("Usage: {} [options] [--] [file]... [+[:]|+:]\n\n" "Options:\n" "{}\n" "Prefixing a positional argument with a plus (`+`) sign will place the\n" From 7e9c4b7f6a5104b6872fa0432c088ff306386e4f Mon Sep 17 00:00:00 2001 From: Philipp Jungkamp Date: Sun, 16 Jun 2024 18:30:25 +0200 Subject: [PATCH 2/4] Remove `--help` commandline special case This special case was not handled in the `ParametersParser` and therefore did not respect the `--` separator for switches. --- src/main.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main.cc b/src/main.cc index d340ba7ec..52d51b565 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1122,9 +1122,6 @@ int main(int argc, char* argv[]) | transform([](auto* s) { return String{s}; }) | gather>(); - if (contains(params, "--help"_sv)) - return show_usage(); - ParametersParser parser{params, param_desc}; const bool show_help_message = (bool)parser.get_switch("help"); From 0cdb088981405568b945997ff21dc5e55d884499 Mon Sep 17 00:00:00 2001 From: Philipp Jungkamp Date: Sun, 16 Jun 2024 18:32:04 +0200 Subject: [PATCH 3/4] Add `WithCoord` flag to `ParameterDesc` Adding the `WithCoord` flag will make the `ParametersParser` try to parse a special `+:` VIM-style switch. --- src/parameters_parser.cc | 20 ++++++++++++++++++++ src/parameters_parser.hh | 6 +++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/parameters_parser.cc b/src/parameters_parser.cc index 755753239..e01dfddc1 100644 --- a/src/parameters_parser.cc +++ b/src/parameters_parser.cc @@ -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 switch_seen(desc.switches.size(), false); for (size_t i = 0; i < params.size(); ++i) @@ -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); diff --git a/src/parameters_parser.hh b/src/parameters_parser.hh index c11dc5012..ba32a366e 100644 --- a/src/parameters_parser.hh +++ b/src/parameters_parser.hh @@ -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" @@ -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) { return true; } @@ -142,12 +144,14 @@ struct ParametersParser iterator end() const { return iterator(*this, m_positional_indices.size()); } State state() const { return *m_state; } + Optional get_coord() const { return m_coord; } private: ParameterList m_params; Vector m_positional_indices; HashMap m_switches; Optional m_state; + Optional m_coord; }; } From 312002700fbcd945435fe449e338cfb023d1bd84 Mon Sep 17 00:00:00 2001 From: Philipp Jungkamp Date: Sun, 16 Jun 2024 18:34:06 +0200 Subject: [PATCH 4/4] Use `WithCoord` parameter parsing for argv This moves the parameter parsing for the `+:` switch of the commandline to the `ParametersParser`. The position switch now respects the `--` separator between switches and files. --- src/main.cc | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/main.cc b/src/main.cc index 52d51b565..a9b824cee 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1102,7 +1102,8 @@ 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 @@ -1182,32 +1183,8 @@ int main(int argc, char* argv[]) parser.get_switch("i").value_or(StringView{})); } - Vector files; - Optional 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({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>(); if (auto server_session = parser.get_switch("c")) { @@ -1219,14 +1196,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);