mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 05:28:49 +00:00
Clean up some job status messages
Stop printing anything for jobs terminated via ^C. Don't list the job number if it's the only job. Fixes #1119
This commit is contained in:
parent
c31ad3ed07
commit
6db82c162c
2 changed files with 83 additions and 25 deletions
107
proc.cpp
107
proc.cpp
|
@ -103,13 +103,17 @@ job_iterator_t::job_iterator_t(job_list_t &jobs) : job_list(&jobs)
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
job_iterator_t::job_iterator_t() : job_list(&parser_t::principal_parser().job_list())
|
job_iterator_t::job_iterator_t() : job_list(&parser_t::principal_parser().job_list())
|
||||||
{
|
{
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t job_iterator_t::count() const
|
||||||
|
{
|
||||||
|
return this->job_list->size();
|
||||||
|
}
|
||||||
|
|
||||||
void print_jobs(void)
|
void print_jobs(void)
|
||||||
{
|
{
|
||||||
job_iterator_t jobs;
|
job_iterator_t jobs;
|
||||||
|
@ -644,16 +648,55 @@ void job_handle_signal(int signal, siginfo_t *info, void *con)
|
||||||
got_signal = 1;
|
got_signal = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given a command like "cat file", truncate it to a reasonable length */
|
||||||
|
static wcstring truncate_command(const wcstring &cmd)
|
||||||
|
{
|
||||||
|
const size_t max_len = 32;
|
||||||
|
if (cmd.size() <= max_len)
|
||||||
|
{
|
||||||
|
// No truncation necessary
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncation required
|
||||||
|
const bool ellipsis_is_unicode = (ellipsis_char == L'\x2026');
|
||||||
|
const size_t ellipsis_length = ellipsis_is_unicode ? 1 : 3;
|
||||||
|
size_t trunc_length = max_len - ellipsis_length;
|
||||||
|
// Eat trailing whitespace
|
||||||
|
while (trunc_length > 0 && iswspace(cmd.at(trunc_length - 1)))
|
||||||
|
{
|
||||||
|
trunc_length -= 1;
|
||||||
|
}
|
||||||
|
wcstring result = wcstring(cmd, 0, trunc_length);
|
||||||
|
// Append ellipsis
|
||||||
|
if (ellipsis_is_unicode)
|
||||||
|
{
|
||||||
|
result.push_back(ellipsis_char);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.append(L"...");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Format information about job status for the user to look at.
|
Format information about job status for the user to look at.
|
||||||
|
|
||||||
\param j the job to test
|
\param j the job to test
|
||||||
\param status a string description of the job exit type
|
\param status a string description of the job exit type
|
||||||
*/
|
*/
|
||||||
static void format_job_info(const job_t *j, const wchar_t *status)
|
static void format_job_info(const job_t *j, const wchar_t *status, size_t job_count)
|
||||||
{
|
{
|
||||||
fwprintf(stdout, L"\r");
|
fwprintf(stdout, L"\r");
|
||||||
fwprintf(stdout, _(L"Job %d, \'%ls\' has %ls"), j->job_id, j->command_wcstr(), status);
|
if (job_count == 1)
|
||||||
|
{
|
||||||
|
fwprintf(stdout, _(L"\'%ls\' has %ls"), truncate_command(j->command()).c_str(), status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwprintf(stdout, _(L"Job %d, \'%ls\' has %ls"), j->job_id, truncate_command(j->command()).c_str(), status);
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
tputs(clr_eol,1,&writeb);
|
tputs(clr_eol,1,&writeb);
|
||||||
fwprintf(stdout, L"\n");
|
fwprintf(stdout, L"\n");
|
||||||
|
@ -692,6 +735,7 @@ int job_reap(bool interactive)
|
||||||
const int saved_status = proc_get_last_status();
|
const int saved_status = proc_get_last_status();
|
||||||
|
|
||||||
job_iterator_t jobs;
|
job_iterator_t jobs;
|
||||||
|
const size_t job_count = jobs.count();
|
||||||
jnext = jobs.next();
|
jnext = jobs.next();
|
||||||
while (jnext)
|
while (jnext)
|
||||||
{
|
{
|
||||||
|
@ -734,26 +778,39 @@ int job_reap(bool interactive)
|
||||||
job_set_flag(j, JOB_NOTIFIED, 1);
|
job_set_flag(j, JOB_NOTIFIED, 1);
|
||||||
if (!job_get_flag(j, JOB_SKIP_NOTIFICATION))
|
if (!job_get_flag(j, JOB_SKIP_NOTIFICATION))
|
||||||
{
|
{
|
||||||
if (proc_is_job)
|
/* Print nothing if we get SIGINT in the foreground process group, to avoid spamming obvious stuff on the console (#1119). If we get SIGINT for the foreground process, assume the user typed ^C and can see it working. It's possible they didn't, and the signal was delivered via pkill, etc., but the SIGINT/SIGTERM distinction is precisely to allow INT to be from a UI and TERM to be programmatic, so this assumption is keeping with the design of signals.
|
||||||
fwprintf(stdout,
|
If echoctl is on, then the terminal will have written ^C to the console. If off, it won't have. We don't echo ^C either way, so as to respect the user's preference. */
|
||||||
_(L"%ls: Job %d, \'%ls\' terminated by signal %ls (%ls)"),
|
if (WTERMSIG(p->status) != SIGINT || ! job_get_flag(j, JOB_FOREGROUND))
|
||||||
program_name,
|
{
|
||||||
j->job_id,
|
if (proc_is_job)
|
||||||
j->command_wcstr(),
|
{
|
||||||
sig2wcs(WTERMSIG(p->status)),
|
// We want to report the job number, unless it's the only job, in which case we don't need to
|
||||||
signal_get_desc(WTERMSIG(p->status)));
|
const wcstring job_number_desc = (job_count == 1) ? wcstring() : format_string(L"Job %d, ", j->job_id);
|
||||||
else
|
fwprintf(stdout,
|
||||||
fwprintf(stdout,
|
_(L"%ls: %ls\'%ls\' terminated by signal %ls (%ls)"),
|
||||||
_(L"%ls: Process %d, \'%ls\' from job %d, \'%ls\' terminated by signal %ls (%ls)"),
|
program_name,
|
||||||
program_name,
|
job_number_desc.c_str(),
|
||||||
p->pid,
|
truncate_command(j->command()).c_str(),
|
||||||
p->argv0(),
|
sig2wcs(WTERMSIG(p->status)),
|
||||||
j->job_id,
|
signal_get_desc(WTERMSIG(p->status)));
|
||||||
j->command_wcstr(),
|
}
|
||||||
sig2wcs(WTERMSIG(p->status)),
|
else
|
||||||
signal_get_desc(WTERMSIG(p->status)));
|
{
|
||||||
tputs(clr_eol,1,&writeb);
|
const wcstring job_number_desc = (job_count == 1) ? wcstring() : format_string(L"from job %d, ", j->job_id);
|
||||||
fwprintf(stdout, L"\n");
|
// This case is pretty rare
|
||||||
|
fwprintf(stdout,
|
||||||
|
_(L"%ls: Process %d, \'%ls\' %ls\'%ls\' terminated by signal %ls (%ls)"),
|
||||||
|
program_name,
|
||||||
|
p->pid,
|
||||||
|
p->argv0(),
|
||||||
|
job_number_desc.c_str(),
|
||||||
|
truncate_command(j->command()).c_str(),
|
||||||
|
sig2wcs(WTERMSIG(p->status)),
|
||||||
|
signal_get_desc(WTERMSIG(p->status)));
|
||||||
|
}
|
||||||
|
tputs(clr_eol,1,&writeb);
|
||||||
|
fwprintf(stdout, L"\n");
|
||||||
|
}
|
||||||
found=1;
|
found=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,7 +830,7 @@ int job_reap(bool interactive)
|
||||||
{
|
{
|
||||||
if (!job_get_flag(j, JOB_FOREGROUND) && !job_get_flag(j, JOB_NOTIFIED) && !job_get_flag(j, JOB_SKIP_NOTIFICATION))
|
if (!job_get_flag(j, JOB_FOREGROUND) && !job_get_flag(j, JOB_NOTIFIED) && !job_get_flag(j, JOB_SKIP_NOTIFICATION))
|
||||||
{
|
{
|
||||||
format_job_info(j, _(L"ended"));
|
format_job_info(j, _(L"ended"), job_count);
|
||||||
found=1;
|
found=1;
|
||||||
}
|
}
|
||||||
proc_fire_event(L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0);
|
proc_fire_event(L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0);
|
||||||
|
@ -788,7 +845,7 @@ int job_reap(bool interactive)
|
||||||
*/
|
*/
|
||||||
if (!job_get_flag(j, JOB_SKIP_NOTIFICATION))
|
if (!job_get_flag(j, JOB_SKIP_NOTIFICATION))
|
||||||
{
|
{
|
||||||
format_job_info(j, _(L"stopped"));
|
format_job_info(j, _(L"stopped"), job_count);
|
||||||
found=1;
|
found=1;
|
||||||
}
|
}
|
||||||
job_set_flag(j, JOB_NOTIFIED, 1);
|
job_set_flag(j, JOB_NOTIFIED, 1);
|
||||||
|
|
1
proc.h
1
proc.h
|
@ -424,6 +424,7 @@ public:
|
||||||
|
|
||||||
job_iterator_t(job_list_t &jobs);
|
job_iterator_t(job_list_t &jobs);
|
||||||
job_iterator_t();
|
job_iterator_t();
|
||||||
|
size_t count() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue