Display a status line message when Kakoune is waiting on a shell to complete

If a shell commands takes more than 1s to execute, a message will appear
on the status line notifying the user, along with the time Kakoune has
been waiting for.
This commit is contained in:
Maxime Coste 2016-10-29 11:25:58 +01:00
parent 965cd8e0c3
commit a7cac87753
5 changed files with 30 additions and 8 deletions

View File

@ -98,10 +98,18 @@ void Client::handle_available_input(EventMode mode)
}
}
void Client::print_status(DisplayLine status_line)
void Client::print_status(DisplayLine status_line, bool immediate)
{
m_status_line = std::move(status_line);
m_ui_pending |= StatusLine;
if (immediate)
{
m_ui->draw_status(m_status_line, m_mode_line, get_face("StatusLine"));
m_ui->refresh(true);
}
else
{
m_ui_pending |= StatusLine;
}
}
DisplayLine Client::generate_mode_line() const

View File

@ -41,7 +41,7 @@ public:
void info_show(String title, String content, BufferCoord anchor, InfoStyle style);
void info_hide();
void print_status(DisplayLine status_line);
void print_status(DisplayLine status_line, bool immediate = false);
DisplayCoord dimensions() const { return m_ui->dimensions(); }

View File

@ -69,10 +69,10 @@ void Context::set_window(Window& window)
m_window.reset(&window);
}
void Context::print_status(DisplayLine status) const
void Context::print_status(DisplayLine status, bool immediate) const
{
if (has_client())
client().print_status(std::move(status));
client().print_status(std::move(status), immediate);
}
void JumpList::push(SelectionList jump)

View File

@ -128,7 +128,7 @@ public:
KeymapManager& keymaps() const { return scope().keymaps(); }
AliasRegistry& aliases() const { return scope().aliases(); }
void print_status(DisplayLine status) const;
void print_status(DisplayLine status, bool immediate = false) const;
StringView main_sel_register_value(StringView reg) const;

View File

@ -5,6 +5,8 @@
#include "buffer_utils.hh"
#include "event_manager.hh"
#include "file.hh"
#include "face_registry.hh"
#include "display_buffer.hh"
#include <cstring>
#include <sys/types.h>
@ -150,7 +152,7 @@ std::pair<String, int> ShellManager::eval(
write(child_stdin.write_fd(), input);
child_stdin.close_write_fd();
auto wait_time = profile ? Clock::now() : Clock::time_point{};
auto wait_time = Clock::now();
struct PipeReader : FDWatcher
{
@ -186,6 +188,10 @@ std::pair<String, int> ShellManager::eval(
// check for termination now that SIGCHLD is blocked
bool terminated = waitpid(pid, &status, WNOHANG);
using namespace std::chrono;
static constexpr seconds wait_timeout{1};
auto next_wait_notification = duration_cast<milliseconds>(wait_timeout);
while (not terminated or
((flags & Flags::WaitForStdout) and
(child_stdout.read_fd() != -1 or child_stderr.read_fd() != -1)))
@ -193,6 +199,15 @@ std::pair<String, int> ShellManager::eval(
EventManager::instance().handle_next_events(EventMode::Urgent, &orig_mask);
if (not terminated)
terminated = waitpid(pid, &status, WNOHANG);
auto wait_duration = Clock::now() - wait_time;
if (wait_duration > next_wait_notification)
{
next_wait_notification = duration_cast<milliseconds>(wait_duration + wait_timeout);
context.print_status({ format("waiting for shell command to finish ({}s)",
duration_cast<seconds>(wait_duration).count()),
get_face("Information") }, true);
}
}
if (not stderr_contents.empty())
@ -200,7 +215,6 @@ std::pair<String, int> ShellManager::eval(
if (profile)
{
using namespace std::chrono;
auto end_time = Clock::now();
auto full = duration_cast<milliseconds>(end_time - start_time);
auto spawn = duration_cast<milliseconds>(wait_time - spawn_time);