Display the command prompt in error face when the command is not found

Fixes #1021
This commit is contained in:
Maxime Coste 2016-12-23 16:23:31 +00:00
parent 62df6dbb46
commit d17bed9b80
3 changed files with 27 additions and 21 deletions

View File

@ -479,7 +479,7 @@ void CommandManager::execute(StringView command_line,
execute_single_command(params, context, shell_context, command_coord); execute_single_command(params, context, shell_context, command_coord);
} }
CommandInfo CommandManager::command_info(const Context& context, StringView command_line) const Optional<CommandInfo> CommandManager::command_info(const Context& context, StringView command_line) const
{ {
TokenList tokens = parse<false>(command_line); TokenList tokens = parse<false>(command_line);
size_t cmd_idx = 0; size_t cmd_idx = 0;
@ -489,19 +489,19 @@ CommandInfo CommandManager::command_info(const Context& context, StringView comm
cmd_idx = i+1; cmd_idx = i+1;
} }
CommandInfo res;
if (cmd_idx == tokens.size() or if (cmd_idx == tokens.size() or
(tokens[cmd_idx].type() != Token::Type::Raw and (tokens[cmd_idx].type() != Token::Type::Raw and
tokens[cmd_idx].type() != Token::Type::RawQuoted)) tokens[cmd_idx].type() != Token::Type::RawQuoted))
return res; return {};
auto cmd = find_command(context, tokens[cmd_idx].content()); auto cmd = find_command(context, tokens[cmd_idx].content());
if (cmd == m_commands.end()) if (cmd == m_commands.end())
return res; return {};
res.first = cmd->first; CommandInfo res;
res.name = cmd->first;
if (not cmd->second.docstring.empty()) if (not cmd->second.docstring.empty())
res.second += cmd->second.docstring + "\n"; res.info += cmd->second.docstring + "\n";
if (cmd->second.helper) if (cmd->second.helper)
{ {
@ -520,7 +520,7 @@ CommandInfo CommandManager::command_info(const Context& context, StringView comm
{ {
if (helpstr.back() != '\n') if (helpstr.back() != '\n')
helpstr += '\n'; helpstr += '\n';
res.second += helpstr; res.info += helpstr;
} }
} }
@ -528,14 +528,14 @@ CommandInfo CommandManager::command_info(const Context& context, StringView comm
for (auto& alias : context.aliases().aliases_for(cmd->first)) for (auto& alias : context.aliases().aliases_for(cmd->first))
aliases += " " + alias; aliases += " " + alias;
if (not aliases.empty()) if (not aliases.empty())
res.second += "Aliases:" + aliases + "\n"; res.info += "Aliases:" + aliases + "\n";
auto& switches = cmd->second.param_desc.switches; auto& switches = cmd->second.param_desc.switches;
if (not switches.empty()) if (not switches.empty())
{ {
res.second += "Switches:\n"; res.info += "Switches:\n";
res.second += generate_switches_doc(switches); res.info += generate_switches_doc(switches);
} }
return res; return res;

View File

@ -8,6 +8,7 @@
#include "shell_manager.hh" #include "shell_manager.hh"
#include "parameters_parser.hh" #include "parameters_parser.hh"
#include "string.hh" #include "string.hh"
#include "optional.hh"
#include "utils.hh" #include "utils.hh"
#include "unordered_map.hh" #include "unordered_map.hh"
@ -38,7 +39,7 @@ enum class CommandFlags
template<> struct WithBitOps<CommandFlags> : std::true_type {}; template<> struct WithBitOps<CommandFlags> : std::true_type {};
using CommandInfo = std::pair<String, String>; struct CommandInfo { String name, info; };
struct Token struct Token
{ {
@ -91,7 +92,7 @@ public:
CommandParameters params, CommandParameters params,
size_t token_to_complete, ByteCount pos_in_token); size_t token_to_complete, ByteCount pos_in_token);
CommandInfo command_info(const Context& context, Optional<CommandInfo> command_info(const Context& context,
StringView command_line) const; StringView command_line) const;
bool command_defined(const String& command_name) const; bool command_defined(const String& command_name) const;

View File

@ -366,16 +366,21 @@ void command(Context& context, NormalParams params)
if (context.has_client()) if (context.has_client())
{ {
context.client().info_hide(); context.client().info_hide();
if (event == PromptEvent::Change)
{
auto info = CommandManager::instance().command_info(context, cmdline);
context.input_handler().set_prompt_face(get_face(info ? "Prompt" : "Error"));
auto autoinfo = context.options()["autoinfo"].get<AutoInfo>(); auto autoinfo = context.options()["autoinfo"].get<AutoInfo>();
if (event == PromptEvent::Change and autoinfo & AutoInfo::Command) if (autoinfo & AutoInfo::Command)
{ {
if (cmdline.length() == 1 and is_horizontal_blank(cmdline[0_byte])) if (cmdline.length() == 1 and is_horizontal_blank(cmdline[0_byte]))
context.client().info_show("prompt", "commands preceded by a blank wont be saved to history", context.client().info_show("prompt",
"commands preceded by a blank wont be saved to history",
{}, InfoStyle::Prompt); {}, InfoStyle::Prompt);
else if (info and not info->info.empty())
auto info = CommandManager::instance().command_info(context, cmdline); context.client().info_show(info->name, info->info, {}, InfoStyle::Prompt);
if (not info.first.empty() and not info.second.empty()) }
context.client().info_show(info.first, info.second, {}, InfoStyle::Prompt);
} }
} }
if (event == PromptEvent::Validate) if (event == PromptEvent::Validate)