Report similar names for builtins that user is searching for
This commit is contained in:
parent
92e5c3169c
commit
719e8d4f26
@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Builtin documentation for builtin functions display from repl and command line.
|
||||
- Builtin documentation for builtin functions display from repl and command line (`musique doc <builtin>`)
|
||||
- Man documentation for commandline interface builtin (`musique man`)
|
||||
- Suggestions which command line parameters user may wanted to use
|
||||
|
||||
### Changed
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
// TODO: Command line parameters full documentation in other then man pages format. Maybe HTML generation?
|
||||
|
||||
#ifdef _WIN32
|
||||
extern "C" {
|
||||
#include <io.h>
|
||||
@ -53,6 +55,11 @@ static Requires_Argument show_docs = [](std::string_view builtin) {
|
||||
}
|
||||
std::cerr << pretty::begin_error << "musique: error:" << pretty::end;
|
||||
std::cerr << " cannot find documentation for given builtin" << std::endl;
|
||||
|
||||
std::cerr << "Similar ones are:" << std::endl;
|
||||
for (auto similar : similar_names_to_builtin(builtin)) {
|
||||
std::cerr << " " << similar << '\n';
|
||||
}
|
||||
std::exit(1);
|
||||
};
|
||||
|
||||
@ -347,11 +354,12 @@ void cmd::print_close_matches(std::string_view arg)
|
||||
std::cout << "\nInvoke 'musique help' to read more about available commands\n";
|
||||
}
|
||||
|
||||
void cmd::usage()
|
||||
static inline void iterate_over_documentation(
|
||||
std::ostream& out,
|
||||
std::string_view Documentation_For_Handler_Entry::* handler,
|
||||
std::string_view prefix,
|
||||
std::ostream&(*first)(std::ostream&, std::string_view name))
|
||||
{
|
||||
std::cerr << "usage: " << pretty::begin_bold << "musique" << pretty::end << " [subcommand]...\n";
|
||||
std::cerr << " where available subcommands are:\n";
|
||||
|
||||
decltype(std::optional(all_parameters.begin())) previous = std::nullopt;
|
||||
|
||||
for (auto it = all_parameters.begin();; ++it) {
|
||||
@ -361,14 +369,12 @@ void cmd::usage()
|
||||
if (it == all_parameters.end() || (previous && it->handler_ptr() != (*previous)->handler_ptr())) {
|
||||
auto &e = **previous;
|
||||
switch (e.arguments()) {
|
||||
break; case 0: std::cerr << '\n';
|
||||
break; case 1: std::cerr << " ARG\n";
|
||||
break; case 0: out << '\n';
|
||||
break; case 1: out << " ARG\n";
|
||||
break; default: unreachable();
|
||||
}
|
||||
|
||||
std::cerr << " "
|
||||
<< find_documentation_for_handler(e.handler_ptr()).short_documentation
|
||||
<< "\n\n";
|
||||
out << prefix << find_documentation_for_handler(e.handler_ptr()).*handler << "\n\n";
|
||||
}
|
||||
|
||||
if (it == all_parameters.end()) {
|
||||
@ -376,12 +382,24 @@ void cmd::usage()
|
||||
}
|
||||
|
||||
if (previous && (**previous).handler_ptr() == it->handler_ptr()) {
|
||||
std::cerr << ", " << it->name;
|
||||
out << ", " << it->name;
|
||||
} else {
|
||||
std::cerr << " " << pretty::begin_bold << it->name << pretty::end;
|
||||
first(out, it->name);
|
||||
}
|
||||
previous = it;
|
||||
}
|
||||
}
|
||||
|
||||
void cmd::usage()
|
||||
{
|
||||
std::cerr << "usage: " << pretty::begin_bold << "musique" << pretty::end << " [subcommand]...\n";
|
||||
std::cerr << " where available subcommands are:\n";
|
||||
|
||||
iterate_over_documentation(std::cerr, &Documentation_For_Handler_Entry::short_documentation, " ",
|
||||
[](std::ostream& out, std::string_view name) -> std::ostream&
|
||||
{
|
||||
return out << " " << pretty::begin_bold << name << pretty::end;
|
||||
});
|
||||
|
||||
std::exit(2);
|
||||
}
|
||||
@ -411,11 +429,28 @@ SUBCOMMANDS
|
||||
Musique is an interpreted, interactive, musical domain specific programming language
|
||||
that allows for algorythmic music composition, live-coding and orchestra performing.
|
||||
.SH SUBCOMMANDS
|
||||
TODO
|
||||
.SH ENVIROMENT
|
||||
TODO: NO_COLORS env
|
||||
All subcommands can be expressed in three styles: -i arg -j -k
|
||||
.I or
|
||||
--i=arg --j --k
|
||||
.I or
|
||||
i arg j k
|
||||
)troff";
|
||||
|
||||
iterate_over_documentation(std::cout, &Documentation_For_Handler_Entry::long_documentation, {},
|
||||
[](std::ostream& out, std::string_view name) -> std::ostream&
|
||||
{
|
||||
return out << ".TP\n" << name;
|
||||
});
|
||||
|
||||
std::cout << R"troff(.SH ENVIROMENT
|
||||
.TP
|
||||
NO_COLOR
|
||||
This enviroment variable overrides standard Musique color behaviour.
|
||||
When it's defined, it disables colors and ensures they are not enabled.
|
||||
.SH FILES
|
||||
TODO: History file
|
||||
.TP
|
||||
History file
|
||||
History file for interactive mode is kept in XDG_DATA_HOME (or similar on other operating systems).
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
musique \-c "play (c5 + up 12)"
|
||||
@ -425,7 +460,6 @@ musique run examples/ode-to-joy.mq
|
||||
Play Ode to Joy written as Musique source code in examples/ode-to-joy.mq
|
||||
)troff";
|
||||
|
||||
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,12 @@
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
std::optional<std::string_view> find_documentation_for_builtin(std::string_view builtin_name);
|
||||
|
||||
|
||||
/// Returns top 4 similar names to required
|
||||
std::vector<std::string_view> similar_names_to_builtin(std::string_view builtin_name);
|
||||
|
||||
#endif
|
||||
|
@ -70,6 +70,28 @@ std::optional<std::string_view> find_documentation_for_builtin(std::string_view
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<std::string_view> similar_names_to_builtin(std::string_view builtin_name)
|
||||
{
|
||||
auto minimum_distance = std::numeric_limits<int>::max();
|
||||
|
||||
std::array<std::pair<std::string_view, std::string_view>, 4> closest;
|
||||
std::partial_sort_copy(
|
||||
names_to_documentation.begin(), names_to_documentation.end(),
|
||||
closest.begin(), closest.end(),
|
||||
[&minimum_distance, builtin_name](auto const& lhs, auto const& rhs) {
|
||||
auto const lhs_score = edit_distance(builtin_name, lhs.first);
|
||||
auto const rhs_score = edit_distance(builtin_name, rhs.first);
|
||||
minimum_distance = std::min({ minimum_distance, lhs_score, rhs_score });
|
||||
return lhs_score < rhs_score;
|
||||
}
|
||||
);
|
||||
|
||||
std::vector<std::string_view> result;
|
||||
result.resize(4);
|
||||
std::transform(closest.begin(), closest.end(), result.begin(), [](auto const& p) { return p.first; });
|
||||
return result;
|
||||
}
|
||||
"""
|
||||
|
||||
def warning(*args, prefix: str | None = None):
|
||||
@ -238,8 +260,15 @@ def generate_cpp_documentation(builtins: typing.Iterable[Builtin], output_path:
|
||||
return f"{builtin.implementation}_doc"
|
||||
|
||||
with open(output_path, "w") as out:
|
||||
print("#include <array>", file=out)
|
||||
print("#include <musique/interpreter/builtin_function_documentation.hh>\n", file=out)
|
||||
includes = [
|
||||
"algorithm",
|
||||
"array",
|
||||
"edit_distance.hh",
|
||||
"musique/interpreter/builtin_function_documentation.hh",
|
||||
"vector",
|
||||
]
|
||||
for include in includes:
|
||||
print(f"#include <{include}>", file=out)
|
||||
|
||||
# 1. Generate strings with documentation
|
||||
for builtin in builtins:
|
||||
|
Loading…
Reference in New Issue
Block a user