Regenerate shell-candidates for each completion sessions

That should allow fixing the #665 issue while still avoiding to
run a potentially long shell command on each keystroke.
This commit is contained in:
Maxime Coste 2016-08-05 13:53:19 +01:00
parent 38d372567b
commit 5b7b6eebaf
5 changed files with 27 additions and 7 deletions

View File

@ -609,6 +609,11 @@ Completions CommandManager::complete(const Context& context,
return Completions{};
const String& command_name = tokens[cmd_idx].content();
if (command_name != m_last_complete_command)
{
m_last_complete_command = command_name;
flags |= CompletionFlags::Start;
}
auto command_it = find_command(context, command_name);
if (command_it == m_commands.end() or
@ -652,6 +657,11 @@ Completions CommandManager::complete(const Context& context,
else
{
const String& command_name = params[0];
if (command_name != m_last_complete_command)
{
m_last_complete_command = command_name;
flags |= CompletionFlags::Start;
}
auto command_it = find_command(context, command_name);
if (command_it != m_commands.end() and command_it->second.completer)

View File

@ -126,6 +126,8 @@ public:
Completions complete_command_name(const Context& context, StringView query, bool with_aliases) const;
void clear_last_complete_command() { m_last_complete_command = String{}; }
private:
void execute_single_command(CommandParameters params,
Context& context,
@ -143,6 +145,7 @@ private:
};
using CommandMap = UnorderedMap<String, CommandDescriptor, MemoryDomain::Commands>;
CommandMap m_commands;
String m_last_complete_command;
CommandMap::const_iterator find_command(const Context& context,
const String& name) const;

View File

@ -843,7 +843,7 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
CommandParameters params,
size_t token_to_complete, ByteCount pos_in_token)
{
if (flags == CompletionFlags::Fast) // no shell on fast completion
if (flags & CompletionFlags::Fast) // no shell on fast completion
return Completions{};
ShellContext shell_context{
@ -866,9 +866,12 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
const Context& context, CompletionFlags flags, CommandParameters params,
size_t token_to_complete, ByteCount pos_in_token) mutable
{
if (flags & CompletionFlags::Start)
token = -1;
if (token != token_to_complete)
{
if (flags == CompletionFlags::Fast) // no shell on fast completion
if (flags & CompletionFlags::Fast) // no shell on fast completion
return Completions{};
ShellContext shell_context{
@ -884,9 +887,6 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
token = token_to_complete;
}
if (token != token_to_complete)
return Completions{};
StringView query = params[token_to_complete].substr(0, pos_in_token);
UsedLetters query_letters = used_letters(query);
Vector<RankedMatch> matches;

View File

@ -4,6 +4,7 @@
#include <functional>
#include <algorithm>
#include "flags.hh"
#include "units.hh"
#include "string.hh"
#include "vector.hh"
@ -34,9 +35,13 @@ struct Completions
enum class CompletionFlags
{
None,
Fast
None = 0,
Fast = 1 << 0,
Start = 1 << 2,
};
template<> struct WithBitOps<CompletionFlags> : std::true_type {};
using Completer = std::function<Completions (const Context&, CompletionFlags,
StringView, ByteCount)>;

View File

@ -335,6 +335,8 @@ void command(Context& context, NormalParams params)
if (not CommandManager::has_instance())
return;
CommandManager::instance().clear_last_complete_command();
context.input_handler().prompt(
":", "", get_face("Prompt"), false,
[](const Context& context, CompletionFlags flags,