Merge pull request #5820 from ncfavier/completion-nospace

Don't insert spaces when completing attribute paths
This commit is contained in:
Eelco Dolstra 2021-12-22 17:55:05 +01:00 committed by GitHub
commit b666a2ca8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 10 deletions

View File

@ -7,8 +7,10 @@ function _complete_nix {
local completion=${line%% *} local completion=${line%% *}
if [[ -z $have_type ]]; then if [[ -z $have_type ]]; then
have_type=1 have_type=1
if [[ $completion = filenames ]]; then if [[ $completion == filenames ]]; then
compopt -o filenames compopt -o filenames
elif [[ $completion == attrs ]]; then
compopt -o nospace
fi fi
else else
COMPREPLY+=("$completion") COMPREPLY+=("$completion")

View File

@ -19,7 +19,6 @@ end
function _nix_accepts_files function _nix_accepts_files
set -l response (_nix_complete) set -l response (_nix_complete)
# First line is either filenames or no-filenames.
test $response[1] = 'filenames' test $response[1] = 'filenames'
end end

View File

@ -191,7 +191,7 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
auto sep = prefix_.rfind('.'); auto sep = prefix_.rfind('.');
std::string searchWord; std::string searchWord;
if (sep != std::string::npos) { if (sep != std::string::npos) {
searchWord = prefix_.substr(sep, std::string::npos); searchWord = prefix_.substr(sep + 1, std::string::npos);
prefix_ = prefix_.substr(0, sep); prefix_ = prefix_.substr(0, sep);
} else { } else {
searchWord = prefix_; searchWord = prefix_;
@ -203,6 +203,8 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
Value v2; Value v2;
state->autoCallFunction(*autoArgs, v1, v2); state->autoCallFunction(*autoArgs, v1, v2);
completionType = ctAttrs;
if (v2.type() == nAttrs) { if (v2.type() == nAttrs) {
for (auto & i : *v2.attrs) { for (auto & i : *v2.attrs) {
std::string name = i.name; std::string name = i.name;
@ -232,7 +234,9 @@ void completeFlakeRefWithFragment(
prefix. */ prefix. */
try { try {
auto hash = prefix.find('#'); auto hash = prefix.find('#');
if (hash != std::string::npos) { if (hash == std::string::npos) {
completeFlakeRef(evalState->store, prefix);
} else {
auto fragment = prefix.substr(hash + 1); auto fragment = prefix.substr(hash + 1);
auto flakeRefS = std::string(prefix.substr(0, hash)); auto flakeRefS = std::string(prefix.substr(0, hash));
// FIXME: do tilde expansion. // FIXME: do tilde expansion.
@ -248,6 +252,8 @@ void completeFlakeRefWithFragment(
flake. */ flake. */
attrPathPrefixes.push_back(""); attrPathPrefixes.push_back("");
completionType = ctAttrs;
for (auto & attrPathPrefixS : attrPathPrefixes) { for (auto & attrPathPrefixS : attrPathPrefixes) {
auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS); auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS);
auto attrPathS = attrPathPrefixS + std::string(fragment); auto attrPathS = attrPathPrefixS + std::string(fragment);
@ -285,8 +291,6 @@ void completeFlakeRefWithFragment(
} catch (Error & e) { } catch (Error & e) {
warn(e.msg()); warn(e.msg());
} }
completeFlakeRef(evalState->store, prefix);
} }
void completeFlakeRef(ref<Store> store, std::string_view prefix) void completeFlakeRef(ref<Store> store, std::string_view prefix)

View File

@ -39,7 +39,7 @@ void Completions::add(std::string completion, std::string description)
bool Completion::operator<(const Completion & other) const bool Completion::operator<(const Completion & other) const
{ return completion < other.completion || (completion == other.completion && description < other.description); } { return completion < other.completion || (completion == other.completion && description < other.description); }
bool pathCompletions = false; CompletionType completionType = ctNormal;
std::shared_ptr<Completions> completions; std::shared_ptr<Completions> completions;
std::string completionMarker = "___COMPLETE___"; std::string completionMarker = "___COMPLETE___";
@ -277,7 +277,7 @@ Args::Flag Args::Flag::mkHashTypeOptFlag(std::string && longName, std::optional<
static void _completePath(std::string_view prefix, bool onlyDirs) static void _completePath(std::string_view prefix, bool onlyDirs)
{ {
pathCompletions = true; completionType = ctFilenames;
glob_t globbuf; glob_t globbuf;
int flags = GLOB_NOESCAPE | GLOB_TILDE; int flags = GLOB_NOESCAPE | GLOB_TILDE;
#ifdef GLOB_ONLYDIR #ifdef GLOB_ONLYDIR

View File

@ -237,7 +237,13 @@ public:
void add(std::string completion, std::string description = ""); void add(std::string completion, std::string description = "");
}; };
extern std::shared_ptr<Completions> completions; extern std::shared_ptr<Completions> completions;
extern bool pathCompletions;
enum CompletionType {
ctNormal,
ctFilenames,
ctAttrs
};
extern CompletionType completionType;
std::optional<std::string> needsCompletion(std::string_view s); std::optional<std::string> needsCompletion(std::string_view s);

View File

@ -310,7 +310,14 @@ void mainWrapped(int argc, char * * argv)
Finally printCompletions([&]() Finally printCompletions([&]()
{ {
if (completions) { if (completions) {
std::cout << (pathCompletions ? "filenames\n" : "no-filenames\n"); switch (completionType) {
case ctNormal:
std::cout << "normal\n"; break;
case ctFilenames:
std::cout << "filenames\n"; break;
case ctAttrs:
std::cout << "attrs\n"; break;
}
for (auto & s : *completions) for (auto & s : *completions)
std::cout << s.completion << "\t" << s.description << "\n"; std::cout << s.completion << "\t" << s.description << "\n";
} }