window: support early exit from the readline prompt with Ctrl-{C,G}
This commit is contained in:
@@ -226,6 +226,10 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
Statusbar::printf("Error: %1%", e.errorMessage());
|
Statusbar::printf("Error: %1%", e.errorMessage());
|
||||||
}
|
}
|
||||||
|
catch (NC::PromptAborted &)
|
||||||
|
{
|
||||||
|
Statusbar::printf("Action aborted");
|
||||||
|
}
|
||||||
|
|
||||||
if (myScreen == myPlaylist)
|
if (myScreen == myPlaylist)
|
||||||
myPlaylist->EnableHighlighting();
|
myPlaylist->EnableHighlighting();
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
namespace {
|
namespace {
|
||||||
namespace rl {
|
namespace rl {
|
||||||
|
|
||||||
|
bool aborted;
|
||||||
|
|
||||||
NC::Window *w;
|
NC::Window *w;
|
||||||
size_t start_x;
|
size_t start_x;
|
||||||
size_t start_y;
|
size_t start_y;
|
||||||
@@ -380,12 +382,22 @@ void initScreen(GNUC_UNUSED const char *window_title, bool enable_colors)
|
|||||||
noecho();
|
noecho();
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
|
|
||||||
rl_initialize();
|
|
||||||
// disable autocompletion
|
// disable autocompletion
|
||||||
rl_attempted_completion_function = [](const char *, int, int) -> char ** {
|
rl_attempted_completion_function = [](const char *, int, int) -> char ** {
|
||||||
rl_attempted_completion_over = 1;
|
rl_attempted_completion_over = 1;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
auto abort_prompt = [](int, int) -> int {
|
||||||
|
rl::aborted = true;
|
||||||
|
rl_done = 1;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
// if ctrl-c or ctrl-g is pressed, abort the prompt
|
||||||
|
rl_bind_key(KEY_CTRL_C, abort_prompt);
|
||||||
|
rl_bind_key(KEY_CTRL_G, abort_prompt);
|
||||||
|
// do not change the state of the terminal
|
||||||
|
rl_prep_term_function = nullptr;
|
||||||
|
rl_deprep_term_function = nullptr;
|
||||||
// do not catch signals
|
// do not catch signals
|
||||||
rl_catch_signals = 0;
|
rl_catch_signals = 0;
|
||||||
// overwrite readline callbacks
|
// overwrite readline callbacks
|
||||||
@@ -796,6 +808,7 @@ void Window::pushChar(int ch)
|
|||||||
|
|
||||||
std::string Window::getString(const std::string &base, size_t width, bool encrypted)
|
std::string Window::getString(const std::string &base, size_t width, bool encrypted)
|
||||||
{
|
{
|
||||||
|
rl::aborted = false;
|
||||||
rl::w = this;
|
rl::w = this;
|
||||||
getyx(m_window, rl::start_y, rl::start_x);
|
getyx(m_window, rl::start_y, rl::start_x);
|
||||||
rl::width = width;
|
rl::width = width;
|
||||||
@@ -826,6 +839,9 @@ std::string Window::getString(const std::string &base, size_t width, bool encryp
|
|||||||
free(input);
|
free(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rl::aborted)
|
||||||
|
throw PromptAborted(std::move(result));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/window.h
14
src/window.h
@@ -112,6 +112,20 @@
|
|||||||
/// wrappers over original curses library
|
/// wrappers over original curses library
|
||||||
namespace NC {//
|
namespace NC {//
|
||||||
|
|
||||||
|
/// Thrown if Ctrl-G is pressed during the call to Window::getString().
|
||||||
|
/// @see Window::getString()
|
||||||
|
struct PromptAborted : std::exception
|
||||||
|
{
|
||||||
|
template <typename ArgT>
|
||||||
|
PromptAborted(ArgT &&prompt)
|
||||||
|
: m_prompt(std::forward<ArgT>(prompt)) { }
|
||||||
|
|
||||||
|
virtual const char *what() const noexcept OVERRIDE { return m_prompt.c_str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_prompt;
|
||||||
|
};
|
||||||
|
|
||||||
/// Colors used by NCurses
|
/// Colors used by NCurses
|
||||||
enum class Color { Default, Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, End };
|
enum class Color { Default, Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, End };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user