eldritch horrors
b0d7a81613
clangd broke because it can't look through symlinks. compile_commands
manipulation does not fix it, clangd configuration does not fix it, a
vfs overlay does not fix it, and while a combination of those can fix
it with a bind mount in place that's just too cursed to even consider
clangd bug: https://github.com/llvm/llvm-project/issues/116877
Change-Id: I8e3e8489548eb3a7aa65ac9d12a5ec8abf814aec
110 lines
2 KiB
C++
110 lines
2 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include "lix/libutil/comparator.hh"
|
|
|
|
#include <set>
|
|
#include <string_view>
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
namespace nix {
|
|
|
|
int levenshteinDistance(std::string_view first, std::string_view second);
|
|
|
|
/**
|
|
* A potential suggestion for the cli interface.
|
|
*/
|
|
class Suggestion {
|
|
public:
|
|
/// The smaller the better
|
|
int distance;
|
|
std::string suggestion;
|
|
|
|
std::string to_string() const;
|
|
|
|
GENERATE_CMP(Suggestion, me->distance, me->suggestion)
|
|
};
|
|
|
|
class Suggestions {
|
|
public:
|
|
std::set<Suggestion> suggestions;
|
|
|
|
std::string to_string() const;
|
|
|
|
Suggestions trim(
|
|
int limit = 5,
|
|
int maxDistance = 2
|
|
) const;
|
|
|
|
static Suggestions bestMatches (
|
|
std::set<std::string> allMatches,
|
|
std::string query
|
|
);
|
|
|
|
Suggestions& operator+=(const Suggestions & other);
|
|
};
|
|
|
|
std::ostream & operator<<(std::ostream & str, const Suggestion &);
|
|
std::ostream & operator<<(std::ostream & str, const Suggestions &);
|
|
|
|
/**
|
|
* Either a value of type `T`, or some suggestions
|
|
*/
|
|
template<typename T>
|
|
class OrSuggestions {
|
|
public:
|
|
using Raw = std::variant<T, Suggestions>;
|
|
|
|
Raw raw;
|
|
|
|
T* operator ->()
|
|
{
|
|
return &**this;
|
|
}
|
|
|
|
T& operator *()
|
|
{
|
|
return std::get<T>(raw);
|
|
}
|
|
|
|
operator bool() const noexcept
|
|
{
|
|
return std::holds_alternative<T>(raw);
|
|
}
|
|
|
|
OrSuggestions(T t)
|
|
: raw(t)
|
|
{
|
|
}
|
|
|
|
OrSuggestions()
|
|
: raw(Suggestions{})
|
|
{
|
|
}
|
|
|
|
static OrSuggestions<T> failed(const Suggestions & s)
|
|
{
|
|
auto res = OrSuggestions<T>();
|
|
res.raw = s;
|
|
return res;
|
|
}
|
|
|
|
static OrSuggestions<T> failed()
|
|
{
|
|
return OrSuggestions<T>::failed(Suggestions{});
|
|
}
|
|
|
|
const Suggestions & getSuggestions()
|
|
{
|
|
static Suggestions noSuggestions;
|
|
if (const auto & suggestions = std::get_if<Suggestions>(&raw))
|
|
return *suggestions;
|
|
else
|
|
return noSuggestions;
|
|
}
|
|
|
|
};
|
|
|
|
}
|